home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnusmalltalk / float.st < prev    next >
Text File  |  1992-02-15  |  6KB  |  233 lines

  1. "======================================================================
  2. |
  3. |   Float Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbb         24 Mar 91      Fixed up floating point printing to take account of
  34. |              the number of digits printed in the integer part when
  35. |              printing the fractional part.
  36. |
  37. | sbb         16 Mar 91      Class creation now separate statement.
  38. |
  39. | sbb         20 Sep 90      Fixed storeOn: to not be recursive.
  40. |
  41. | sbyrne     15 Apr 90      Added asFloat...I could have sworn this was already
  42. |                         here...must have been lost in an edit.
  43. |
  44. | sbyrne     25 Apr 89      created.
  45. |
  46. "
  47.  
  48. Number variableWordSubclass: #Float "not really a variable class"
  49.        instanceVariableNames: ''
  50.        classVariableNames: ''
  51.        poolDictionaries: ''
  52.        category: nil
  53. !
  54.  
  55. Float comment: 
  56. 'My instances represent floating point numbers that have 64 bits of 
  57. precision (well, less than that in precision; they are precisely the same
  58. as C''s "double" datatype).  Besides the standard numerical operations,
  59. I provide transcendental operations too.'  !
  60.  
  61. !Float class methodsFor: 'basic'!
  62.  
  63. pi
  64.     "Returns the value of pi"
  65.     ^3.14159265358979323846264338327950288
  66. !!
  67.  
  68.  
  69.  
  70. !Float methodsFor: 'arithmetic'!
  71.  
  72. // aNumber
  73.     "Return the integer quotient of dividing the receiver by aNumber with
  74.     truncation towards negative infinity."
  75.     ^(self / aNumber) floor
  76. !
  77.  
  78. \\ aNumber
  79.     "Return the remainder of dividing the receiver by aNumber with
  80.     truncation towards negative infinity."
  81.     ^(self - (self // aNumber * aNumber)) floor
  82. !
  83.  
  84. integerPart
  85.     ^self - self fractionPart
  86. !!
  87.  
  88.  
  89.  
  90. !Float methodsFor: 'coercing methods'!
  91.  
  92. coerce: aNumber
  93.     ^aNumber asFloat
  94. !
  95.  
  96. generality
  97.     ^4
  98. !
  99.  
  100. asFloat
  101.     "Just defined for completeness."
  102.     ^self
  103. !
  104.  
  105. hash
  106.     "Returns the hash value for the receiver (a Float).  If it's representable
  107.     as an integer, we use that value, since it's likely to be much more random,
  108.     but if not, we use the exponent.  Another approach that may be used in 
  109.     the future is to scale the number so that it's within the integer range if
  110.     it's not normally and then return the integer part"
  111.     | expt |
  112.     expt _ self exponent.
  113.     expt >= 0 & (expt < 31)
  114.         ifTrue: [ ^self truncated ]
  115.     ifFalse: [ ^expt ]
  116. !!
  117.  
  118.  
  119.  
  120. !Float methodsFor: 'copying'!
  121.  
  122. shallowCopy
  123.     ^self
  124. !
  125.  
  126. deepCopy
  127.     ^self
  128. !!
  129.  
  130.  
  131.  
  132.  
  133. !Float methodsFor: 'printing'!
  134.  
  135. printOn: aStream
  136.     | num exp |
  137.     (self exponent between: -50 and: 49)
  138.         ifTrue: [ self printFloatOn: aStream ]
  139.     ifFalse: [ exp _ 0.
  140.                num _ self.
  141.            num abs < 1.0
  142.               ifTrue: [ [ num abs < 1.0 ] whileTrue:
  143.                     [ num _ num * 10.0.
  144.                       exp _ exp - 1 ] ]
  145.               ifFalse: [ [num abs >= 10.0] whileTrue:
  146.                               [ num _ num / 10.0.
  147.                       exp _ exp + 1 ] ].
  148.                    num printFloatOn: aStream.
  149.            aStream nextPut: $e.
  150.            exp printOn: aStream ].
  151. !!
  152.  
  153.  
  154.  
  155. !Float methodsFor: 'storing'!
  156.  
  157. storeOn: aStream
  158.     self printOn: aStream
  159. !!
  160.  
  161.  
  162.  
  163. !Float methodsFor: 'private'!
  164.  
  165. printFloatOn: aStream
  166.     | num str intDigits |
  167.     num _ self.
  168.     num < 0.0 ifTrue:
  169.         [ aStream nextPut: $-.
  170.       num _ num negated. ].
  171.     intDigits _ num printIntegerPartOn: aStream.
  172.     aStream nextPut: $..
  173.     num printFracPartOn: aStream digitsPrinted: intDigits.
  174. !
  175.  
  176. printIntegerPartOn: aStream
  177.     | num digitString numDigits |
  178.     num _ self integerPart.
  179.     (digitString _ num revDigitsBase: 10.0) reverseDo:
  180.         [ :char | aStream nextPut: char ].
  181.     numDigits _ digitString size.
  182.     $0 = (digitString at: 1)    "we've been forced to emit a 0; doesn't count"
  183.     ifTrue: [ numDigits _ numDigits - 1 ].
  184.     ^numDigits
  185. !
  186.  
  187. printFracPartOn: aStream digitsPrinted: numDigits
  188.     | num count zeroCount digit digitLimit |
  189.     num _ self fractionPart.
  190.     num = 0.0 ifTrue: [ ^aStream nextPut: $0 ].
  191.     zeroCount _ count _ 0.
  192.  
  193.     " produce the digits, up to a maximum of 15, suppressing trailing
  194.       zeros (ln(2^52)/ln(10)) "
  195.     digitLimit _ 15 - numDigits.
  196.     [ (num ~= 0.0) & (count < digitLimit) ] whileTrue:
  197.         [ num _ num * 10.0.
  198.       digit _ num floor.
  199.       digit = 0        "for trailing zero suppression"
  200.         ifTrue: [ zeroCount _ zeroCount + 1 ]
  201.         ifFalse: [ aStream next: zeroCount put: $0.
  202.                        aStream nextPut: (Character digitValue: digit).
  203.                    zeroCount _ 0 ].
  204.       num _ num fractionPart.
  205.       count _ count + 1 ].
  206.  
  207.     zeroCount = digitLimit ifTrue: [ aStream nextPut: $0 ]
  208. !
  209.  
  210. "AARRGGHH!  Why can't I share this code with integer?  Grrr...."
  211. revDigitsBase: b    
  212.     | str num digit |
  213.     str _ WriteStream on: (String new: 10).
  214.     self = 0.0
  215.         ifTrue: [ str nextPut: $0 ]
  216.     ifFalse: [
  217.             num _ self.
  218.         [ num = 0.0 ] whileFalse:
  219.             [ "stdout nextPutAll: '------------'; nl.
  220.                   num basicPrint.
  221.           (num/b) basicPrint.
  222.           (num/b) fractionPart basicPrint.
  223.           ((num/b) fractionPart * b) basicPrint.
  224.           ((num/b) fractionPart * b) rounded basicPrint."
  225.           digit _ ((num / b) fractionPart * b) rounded.
  226.           str nextPut: (Character digitValue: digit).
  227.           num _ (num / b) integerPart ] ].
  228.     ^str contents
  229. ! !
  230.  
  231.