FixedPoint.st
changeset 6573 4ea758ea3d4b
parent 6570 1d115f1687e3
child 6625 b68451aa35ab
equal deleted inserted replaced
6572:0fb83a635117 6573:4ea758ea3d4b
   164     "
   164     "
   165 !
   165 !
   166 
   166 
   167 numerator:n denominator:d scale:s
   167 numerator:n denominator:d scale:s
   168     ^ self basicNew
   168     ^ self basicNew
   169         setNumerator:n
   169         setNumerator:n denominator:d scale:s;
   170         denominator:d
   170         reduced
   171         scale:s
       
   172 !
   171 !
   173 
   172 
   174 readFrom:aStringOrStream 
   173 readFrom:aStringOrStream 
   175     "return the next FixedPoint from the (character-)stream aStream. 
   174     "return the next FixedPoint from the (character-)stream aStream. 
   176 
   175 
   328      Transcript show:'fixed (exact)  : '; showCR:r.    
   327      Transcript show:'fixed (exact)  : '; showCR:r.    
   329      Transcript show:'fixed (scale2) : '; showCR:(r withScale:2).
   328      Transcript show:'fixed (scale2) : '; showCR:(r withScale:2).
   330 
   329 
   331      Transcript show:'float (inexact): '; showCR:(0.9999999 * 0.9999999).
   330      Transcript show:'float (inexact): '; showCR:(0.9999999 * 0.9999999).
   332     "
   331     "
   333 
       
   334 
       
   335 !
   332 !
   336 
   333 
   337 + aNumber
   334 + aNumber
   338     "return the sum of the receiver and the argument, aNumber.
   335     "return the sum of the receiver and the argument, aNumber.
   339      Redefined to care for the scale if the argument is another fixPoint number.
   336      Redefined to care for the scale if the argument is another fixPoint number.
   340      The resulting scale will be the maximum of the receivers and the
   337      The resulting scale will be the maximum of the receivers and the
   341      arguments scale."
   338      arguments scale."
   342 
   339 
   343     |n d sMax|
   340     |n d sMax|
   344 
   341 
   345     (aNumber isMemberOf:self class) ifTrue:[
   342     (aNumber isMemberOf:SmallInteger) ifTrue:[
   346         n := aNumber numerator.
   343         n := aNumber numerator.
   347         d := aNumber denominator.
   344         d := aNumber denominator.
   348         sMax := scale max:aNumber scale.
   345         sMax := scale max:aNumber scale.
   349 
   346 
   350         "save a multiplication if possible"
   347         "save a multiplication if possible"
   408      a := 1.
   405      a := 1.
   409      b := (FixedPoint fromString:'0.0000001').
   406      b := (FixedPoint fromString:'0.0000001').
   410      Transcript showCR:((a + b) withScale:1).
   407      Transcript showCR:((a + b) withScale:1).
   411      Transcript showCR:(a + b)
   408      Transcript showCR:(a + b)
   412     "
   409     "
   413 
       
   414 
       
   415 !
   410 !
   416 
   411 
   417 - aNumber
   412 - aNumber
   418     "return the difference of the receiver and the argument, aNumber.
   413     "return the difference of the receiver and the argument, aNumber.
   419      Redefined to care for the scale if the argument is another fixPoint number.
   414      Redefined to care for the scale if the argument is another fixPoint number.
   420      The results scale is the maximum of the receivers scale and the arguments
   415      The results scale is the maximum of the receivers scale and the arguments
   421      scale."
   416      scale."
   422 
   417 
   423     |n d sMax|
   418     |n d sMax|
   424 
   419 
   425     (aNumber isMemberOf:self class) ifTrue:[
   420     (aNumber isMemberOf:SmallInteger) ifTrue:[
   426         n := aNumber numerator.
   421         n := aNumber numerator.
   427         d := aNumber denominator.
   422         d := aNumber denominator.
   428         sMax := scale max:aNumber scale.
   423         sMax := scale max:aNumber scale.
   429 
   424 
   430         "save a multiplication if possible"
   425         "save a multiplication if possible"
   496      a := 1.
   491      a := 1.
   497      b := (FixedPoint fromString:'0.0000001').
   492      b := (FixedPoint fromString:'0.0000001').
   498      Transcript showCR:((a - b) withScale:1).
   493      Transcript showCR:((a - b) withScale:1).
   499      Transcript showCR:(a - b)
   494      Transcript showCR:(a - b)
   500     "
   495     "
   501 
       
   502 !
   496 !
   503 
   497 
   504 / aNumber
   498 / aNumber
   505     "return the quotient of the receiver and the argument, aNumber.
   499     "return the quotient of the receiver and the argument, aNumber.
   506      Redefined to care for the scale if the argument is another fixPoint number.
   500      Redefined to care for the scale if the argument is another fixPoint number.
   511 
   505 
   512     (aNumber isMemberOf:SmallInteger) ifTrue:[
   506     (aNumber isMemberOf:SmallInteger) ifTrue:[
   513         ^ (self class 
   507         ^ (self class 
   514                 numerator:numerator
   508                 numerator:numerator
   515                 denominator:(denominator * aNumber)
   509                 denominator:(denominator * aNumber)
   516                 scale:scale) reduced
   510                 scale:scale)
   517     ].
   511     ].
   518 
   512 
   519     (aNumber isMemberOf:self class) ifTrue:[
   513     (aNumber isMemberOf:self class) ifTrue:[
   520         n := numerator * aNumber denominator.
   514         n := numerator * aNumber denominator.
   521         d := denominator * aNumber numerator.
   515         d := denominator * aNumber numerator.
   522         sMax := scale max:aNumber scale.
   516         sMax := scale max:aNumber scale.
   523 
   517 
   524         ^ (self class 
   518         ^ (self class 
   525             numerator:n 
   519             numerator:n 
   526             denominator:d
   520             denominator:d
   527             scale:sMax) reduced
   521             scale:sMax)
   528     ].
   522     ].
   529     ^ aNumber quotientFromFixedPoint:self
   523     ^ aNumber quotientFromFixedPoint:self
   530 
   524 
   531     "                       
   525     "                       
   532      |a r|                     
   526      |a r|                     
   634 asFraction
   628 asFraction
   635     "return the receiver as a fraction"
   629     "return the receiver as a fraction"
   636 
   630 
   637     ^ (Fraction
   631     ^ (Fraction
   638         numerator:numerator
   632         numerator:numerator
   639         denominator:denominator) reduced
   633         denominator:denominator)
   640 
   634 
   641     "
   635     "
   642      (FixedPoint fromString:'0.2')           
   636      (FixedPoint fromString:'0.2')           
   643      (FixedPoint fromString:'0.2') asFraction
   637      (FixedPoint fromString:'0.2') asFraction
   644      (FixedPoint fromString:'0.2') asFloat
   638      (FixedPoint fromString:'0.2') asFloat
   699      Redefined here to preserve the scale."
   693      Redefined here to preserve the scale."
   700 
   694 
   701     ^ (self class 
   695     ^ (self class 
   702         numerator:((anInteger * denominator) - numerator)
   696         numerator:((anInteger * denominator) - numerator)
   703         denominator:denominator
   697         denominator:denominator
   704         scale:scale) reduced
   698         scale:scale)
   705 
       
   706 !
   699 !
   707 
   700 
   708 productFromInteger:anInteger
   701 productFromInteger:anInteger
   709     "sent when an integer does not know how to multiply the receiver.
   702     "sent when an integer does not know how to multiply the receiver.
   710      Redefined here to preserve the scale."
   703      Redefined here to preserve the scale."
   711 
   704 
   712     ^ (self class 
   705     ^ (self class 
   713         numerator:(anInteger * numerator)
   706         numerator:(anInteger * numerator)
   714         denominator:denominator
   707         denominator:denominator
   715         scale:scale) reduced
   708         scale:scale)
   716 
   709 
   717     "Modified: 5.11.1996 / 10:32:28 / cg"
   710     "Modified: 5.11.1996 / 10:32:28 / cg"
   718 
       
   719 
       
   720 !
   711 !
   721 
   712 
   722 quotientFromInteger:anInteger
   713 quotientFromInteger:anInteger
   723     "sent when an integer does not know how to divide by the receiver.
   714     "sent when an integer does not know how to divide by the receiver.
   724      Redefined here to preserve the scale."
   715      Redefined here to preserve the scale."
   725 
   716 
   726     ^ (self class 
   717     ^ (self class 
   727         numerator:(anInteger * denominator)
   718         numerator:(anInteger * denominator)
   728         denominator:numerator
   719         denominator:numerator
   729         scale:scale) reduced
   720         scale:scale)
   730 
   721 
   731     "Modified: 5.11.1996 / 10:32:35 / cg"
   722     "Modified: 5.11.1996 / 10:32:35 / cg"
   732 
       
   733 
       
   734 !
   723 !
   735 
   724 
   736 sumFromInteger:anInteger
   725 sumFromInteger:anInteger
   737     "sent when an integer does not know how to add the receiver.
   726     "sent when an integer does not know how to add the receiver.
   738      Redefined here to preserve the scale."
   727      Redefined here to preserve the scale."
   739 
   728 
   740     ^ (self class 
   729     ^ (self class 
   741         numerator:(numerator + (anInteger * denominator))
   730         numerator:(numerator + (anInteger * denominator))
   742         denominator:denominator
   731         denominator:denominator
   743         scale:scale) reduced
   732         scale:scale)
   744 
   733 
   745     "Modified: 5.11.1996 / 10:32:43 / cg"
   734     "Modified: 5.11.1996 / 10:32:43 / cg"
   746 
       
   747 
       
   748 ! !
   735 ! !
   749 
   736 
   750 !FixedPoint methodsFor:'printing & storing'!
   737 !FixedPoint methodsFor:'printing & storing'!
   751 
   738 
   752 printOn: aStream 
   739 printOn: aStream 
   843         "/ to catch inherited Fraction reduce calls
   830         "/ to catch inherited Fraction reduce calls
   844         self error:'should not happen'.
   831         self error:'should not happen'.
   845         scale := 3
   832         scale := 3
   846     ].
   833     ].
   847 
   834 
       
   835     (denominator < 0) ifTrue:[
       
   836         numerator := numerator negated.
       
   837         denominator := denominator negated
       
   838     ].
       
   839 
   848     denominator == 1 ifTrue:[^ numerator].
   840     denominator == 1 ifTrue:[^ numerator].
   849     numerator == 1 ifTrue:[^ self].
   841     numerator == 1 ifTrue:[^ self].
   850     numerator == 0 ifTrue:[^ 0].
   842     numerator == 0 ifTrue:[^ 0].
   851 
   843 
   852     gc := numerator gcd:denominator.
   844     gc := numerator gcd:denominator.
   853     gc := gc gcd:(10 raisedTo:scale).
   845     gc < 0 ifTrue:[
   854 
   846         gc := gc negated
   855     (gc == 1) ifFalse:[
   847     ].
       
   848     gc := gc gcd:(10 raisedToInteger:scale).
       
   849 
       
   850     (gc ~~ 1) ifTrue:[
   856         numerator := numerator // gc.
   851         numerator := numerator // gc.
   857         denominator := denominator // gc
   852         denominator := denominator // gc.
   858     ].
   853         denominator == 1 ifTrue:[^ numerator].
   859 
   854     ].
   860     (numerator < 0) ifTrue:[
   855 
   861         (denominator < 0) ifTrue:[
       
   862             numerator := numerator negated.
       
   863             denominator := denominator negated
       
   864         ]
       
   865     ].
       
   866     (denominator == 1) ifTrue:[^ numerator].
       
   867     ^ self
   856     ^ self
   868 
       
   869 !
   857 !
   870 
   858 
   871 scale:newScale 
   859 scale:newScale 
   872     "set the scale."
   860     "set the scale."
   873 
   861 
   923 ! !
   911 ! !
   924 
   912 
   925 !FixedPoint class methodsFor:'documentation'!
   913 !FixedPoint class methodsFor:'documentation'!
   926 
   914 
   927 version
   915 version
   928     ^ '$Header: /cvs/stx/stx/libbasic/FixedPoint.st,v 1.13 2002-06-11 10:06:09 stefan Exp $'
   916     ^ '$Header: /cvs/stx/stx/libbasic/FixedPoint.st,v 1.14 2002-06-11 21:41:35 stefan Exp $'
   929 ! !
   917 ! !