home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / lisp / mcl / 1226 < prev    next >
Encoding:
Text File  |  1992-08-14  |  3.0 KB  |  72 lines

  1. Path: sparky!uunet!sun-barr!apple!cambridge.apple.com!wilcox@cmns.think.com
  2. From: wilcox@cmns.think.com
  3. Newsgroups: comp.lang.lisp.mcl
  4. Subject: _numtostring
  5. Message-ID: <9208141328.AA28871@cmns-sun.think.com>
  6. Date: 14 Aug 92 13:28:05 GMT
  7. References: Daniel Berger's message of Thu, 13 Aug 92 11:32:58 PDT <9208131832.AA01924@dewey>
  8. Sender: info-mcl-request@cambridge.apple.com
  9. Lines: 58
  10. Approved: comp.lang.lisp.mcl@Cambridge.Apple.C0M
  11. Original-To: berger@soe.berkeley.edu
  12. Original-Cc: info-mcl@cambridge.apple.com
  13.  
  14.  
  15. >I need to turn an integer into a string -
  16. >
  17. >Does anyone out there know how to make the trap _numtostring work?
  18. >
  19. >Format is too slow.  Without _numtostring it looks like I will have to iterate
  20. >over the digits of an integer and then push the individual chars into
  21. > a vector. 
  22. >
  23. >thanks
  24. >Daniel
  25.  
  26. Hey, what timing! I just happened to have a similar need for speed yesterday.
  27. You're right - format (and prin1-to-string) is much too slow on floats.
  28. The following code is about 5 times faster. It uses #_NumToString via the
  29. macro with-returned-pstrs. (I tried macro-expanding the code and hand-tuning it
  30. since I knew that the number will always be 12 characters or less, but the
  31. code actually got slower! Why...?) Note that this only works for numbers less
  32. than 2^32; larger numbers are subjected to mod 2^32. 
  33.  
  34.   ;; "magnitude of the integer is converted modulo 2^32"
  35.   ;; -- Inside Macintosh I-490
  36.   ;; so result will never be longer than 12 characters
  37.  
  38. Also note that the definition of the trap _numtostring in packages.lisp
  39. has a spelling error: thenum should be the-num (or vice versa).
  40.  
  41. I have not tested this code extensively yet; there may be bugs. No warrantees
  42. expressed, implied, impressed, replied, etc. Enjoy!
  43.  
  44. (deftrap _numtostring ((thenum :signed-long) (thestring (:pointer (:string 255))))
  45.    nil
  46.    (:no-trap (ccl::%gen-trap #xA9EE :d0 the-num :a0 thestring :word 0)))
  47.                                            ^ should be thenum
  48.  
  49. (defun integer-to-string (number)
  50.   "Converts an integer to a string, using the toolbox."
  51.   (with-returned-pstrs ((string ""))
  52.     (#_numtostring number string)
  53.     (%get-string string)
  54.     ))
  55.  
  56. (defun float-to-string (number fractional-digits)
  57.   "Converts a floating-point number to a string, ~
  58.    with a given number of digits following the decimal point."
  59.   (let* ((integral (floor number))
  60.          (int-string (integer-to-string integral)))
  61.     ;; dont mess around with fractions if you dont have to
  62.     (if (zerop fractional-digits)
  63.       (concatenate 'string int-string ".")
  64.       (let* ((fractional (round (* (expt 10 fractional-digits)
  65.                                    (- number integral))))
  66.              (fract-string (integer-to-string fractional))
  67.              ;; pad fraction with enough zeros to separate it from decimal
  68.              (pad-string (make-string (- fractional-digits (length fract-string))
  69.                                       :initial-element #\0)))
  70.         (concatenate 'string int-string "." pad-string fract-string)
  71.         ))))
  72.