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! |