LimitedPrecisionReal.st
changeset 16444 dcf226d85a5a
parent 16405 0d357280097a
child 16636 42a6cf3b51ba
equal deleted inserted replaced
16443:ebedf88fe390 16444:dcf226d85a5a
    68         Fraction FixedPoint
    68         Fraction FixedPoint
    69 "
    69 "
    70 ! !
    70 ! !
    71 
    71 
    72 !LimitedPrecisionReal class methodsFor:'instance creation'!
    72 !LimitedPrecisionReal class methodsFor:'instance creation'!
       
    73 
       
    74 coerce:aNumber
       
    75     ^ self subclassResponsibility.
       
    76 !
    73 
    77 
    74 fromInteger:anInteger
    78 fromInteger:anInteger
    75     "return a float with anInteger's value.
    79     "return a float with anInteger's value.
    76      Since floats have a limited precision, you usually loose bits when doing this
    80      Since floats have a limited precision, you usually loose bits when doing this
    77      (see Float decimalPrecision, LongFloat decimalPrecision."
    81      (see Float decimalPrecision, LongFloat decimalPrecision."
   169 fromNumerator:numerator denominator:denominator
   173 fromNumerator:numerator denominator:denominator
   170     "Create a limited precision real from a Rational.
   174     "Create a limited precision real from a Rational.
   171      This version will answer the nearest flotaing point value,
   175      This version will answer the nearest flotaing point value,
   172      according to IEEE 754 round to nearest even default mode"
   176      according to IEEE 754 round to nearest even default mode"
   173 
   177 
   174     |a b q r exponent floatExponent n ha hb hq q1 eMin zero precision nSubHq|
   178     |a b q r exponent floatExponent n ha hb hq q1 eMin precision nSubHq|
   175 
   179 
   176     a := numerator abs.
   180     a := numerator abs.
   177     b := denominator abs.
   181     b := denominator abs.
   178     ha := a highBit.
   182     ha := a highBit.
   179     hb := b highBit.    
   183     hb := b highBit.    
   180 
   184 
   181     zero := self zero.
       
   182     precision := self precision.
   185     precision := self precision.
   183 
   186 
   184     "If both numerator and denominator are represented exactly in floating point number,
   187     "If both numerator and denominator are represented exactly in floating point number,
   185      then fastest thing to do is to use hardwired float division"
   188      then fastest thing to do is to use hardwired float division"
   186     (ha <= precision and:[hb <= precision]) ifTrue: [
   189     (ha <= precision and:[hb <= precision]) ifTrue: [
   187         ^ (zero coerce:numerator) / (zero coerce:denominator)
   190         ^ (self coerce:numerator) / (self coerce:denominator)
   188     ].
   191     ].
   189 
   192 
   190     "Try and obtain a mantissa with 1 bit excess precision.
   193     "Try and obtain a mantissa with 1 bit excess precision.
   191      First guess is rough, we might get one more bit or one less"
   194      First guess is rough, we might get one more bit or one less"
   192     exponent := ha - hb - precision - 1.
   195     exponent := ha - hb - precision - 1.
   226 
   229 
   227     (numerator negative xor:denominator negative) ifTrue: [
   230     (numerator negative xor:denominator negative) ifTrue: [
   228         q := q negated.
   231         q := q negated.
   229     ].
   232     ].
   230 
   233 
   231     ^ (zero coerce:q) timesTwoPower:exponent
   234     ^ (self coerce:q) timesTwoPower:exponent
   232 
   235 
   233     "
   236     "
   234         Time millisecondsToRun:[
   237         Time millisecondsToRun:[
   235             1000000  timesRepeat:[
   238             1000000  timesRepeat:[
   236                 Float fromNumerator:12345678901234567890 denominator:987654321
   239                 Float fromNumerator:12345678901234567890 denominator:987654321
   249 
   252 
   250 new:aNumber
   253 new:aNumber
   251     "catch this message - not allowed for floats/doubles"
   254     "catch this message - not allowed for floats/doubles"
   252 
   255 
   253     self error:'Floats/Doubles cannot be created with new:'
   256     self error:'Floats/Doubles cannot be created with new:'
       
   257 !
       
   258 
       
   259 readFrom:aStringOrStream onError:exceptionBlock
       
   260     "read a float from a string"
       
   261 
       
   262     |num|
       
   263 
       
   264     num := super readFrom:aStringOrStream onError:exceptionBlock.
       
   265     ^ self coerce:num
       
   266 
       
   267     "
       
   268      Float readFrom:'.1'
       
   269      Float readFrom:'0.1'
       
   270      Float readFrom:'0'
       
   271 
       
   272      ShortFloat readFrom:'.1'
       
   273      ShortFloat readFrom:'0.1'
       
   274      ShortFloat readFrom:'0'
       
   275 
       
   276      LongFloat readFrom:'.1'
       
   277      LongFloat readFrom:'0.1'
       
   278      LongFloat readFrom:'0'
       
   279     "
       
   280 
       
   281     "Created: / 07-01-1998 / 16:17:19 / cg"
       
   282     "Modified: / 23-11-2010 / 14:35:41 / cg"
   254 ! !
   283 ! !
   255 
   284 
   256 !LimitedPrecisionReal class methodsFor:'class initialization'!
   285 !LimitedPrecisionReal class methodsFor:'class initialization'!
   257 
   286 
   258 initialize
   287 initialize
   524      Implementation takes care of preserving class and avoiding overflow/underflow
   553      Implementation takes care of preserving class and avoiding overflow/underflow
   525      Thanks to Nicolas Cellier for this code"
   554      Thanks to Nicolas Cellier for this code"
   526 
   555 
   527     |half two h1 h2|
   556     |half two h1 h2|
   528 
   557 
   529     two := self coerce:2.
   558     two := self coerce:2.0.
   530 
   559 
   531     anInteger abs highBit >= (self class numBitsInExponent - 2) ifTrue:[
   560     anInteger abs highBit >= (self class numBitsInExponent - 2) ifTrue:[
   532         half := anInteger // 2.
   561         half := anInteger // 2.
   533 
   562 
   534         anInteger even ifTrue:[
   563         anInteger even ifTrue:[
  1180 ! !
  1209 ! !
  1181 
  1210 
  1182 !LimitedPrecisionReal class methodsFor:'documentation'!
  1211 !LimitedPrecisionReal class methodsFor:'documentation'!
  1183 
  1212 
  1184 version
  1213 version
  1185     ^ '$Header: /cvs/stx/stx/libbasic/LimitedPrecisionReal.st,v 1.73 2014-05-07 14:31:21 stefan Exp $'
  1214     ^ '$Header: /cvs/stx/stx/libbasic/LimitedPrecisionReal.st,v 1.74 2014-05-14 14:59:55 stefan Exp $'
  1186 !
  1215 !
  1187 
  1216 
  1188 version_CVS
  1217 version_CVS
  1189     ^ '$Header: /cvs/stx/stx/libbasic/LimitedPrecisionReal.st,v 1.73 2014-05-07 14:31:21 stefan Exp $'
  1218     ^ '$Header: /cvs/stx/stx/libbasic/LimitedPrecisionReal.st,v 1.74 2014-05-14 14:59:55 stefan Exp $'
  1190 ! !
  1219 ! !
  1191 
  1220 
  1192 
  1221 
  1193 LimitedPrecisionReal initialize!
  1222 LimitedPrecisionReal initialize!