[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] Re: [PATCH] fix FloatQ reading
From: |
Nicolas Cellier |
Subject: |
[Help-smalltalk] Re: [PATCH] fix FloatQ reading |
Date: |
Fri, 17 Jul 2009 00:10:13 +0200 |
Too many lines of C for a source code analysis to my own taste :)
Maybe some very simple tests like:
self assert: 1.3q0 = (13/10) asFloatQ.
I wrote Float>>successor recently in Pharo, that can be a helper iin
such tests...
successor
| mantissa biasedExponent |
self isFinite ifFalse: [
(self isNaN or: [self positive]) ifTrue: [^self].
^Float fmax negated].
self = 0.0 ifTrue: [^Float fmin].
mantissa := self significandAsInteger.
(mantissa isPowerOfTwo and: [self negative]) ifTrue: [mantissa :=
mantissa bitShift: 1].
biasedExponent := self exponent - mantissa highBit + 1.
^self sign * (mantissa + self sign) asFloat timesTwoPower:
biasedExponent
predecessor
| mantissa biasedExponent |
self isFinite ifFalse: [
(self isNaN or: [self negative]) ifTrue: [^self].
^Float fmax].
self = 0.0 ifTrue: [^Float fmin negated].
mantissa := self significandAsInteger.
(mantissa isPowerOfTwo and: [self positive]) ifTrue: [mantissa :=
mantissa bitShift: 1].
biasedExponent := self exponent - mantissa highBit + 1.
^self sign * (mantissa - self sign) asFloat timesTwoPower:
biasedExponent
"sanity check in preamble"
self assert: 1.3q0 asExactFraction asFloatQ = 1.3q0.
"Is it the nearest FloatQ?"
self assert: (1.3q0 successor asExactFraction - (13/10)) abs >= (1.3q0
asExactFraction - (13/10)) abs.
self assert: (1.3q0 predecessor asExactFraction - (13/10)) abs >=
(1.3q0 asExactFraction - (13/10)) abs.
"or also written"
self assert: (1.3q0 successor - (13/10) asFloatQ) abs >= (1.3q0 -
(13/10) asFloatQ) abs.
self assert: (1.3q0 predecessor - (13/10) asFloatQ) abs >= (1.3q0 -
(13/10) asFloatQ) abs.
Then instead of 13/10, use some random generator m/(10 raisedTo: n),
generate a string notation from this, read a FloatQ and compare...
2009/7/11 Paolo Bonzini <address@hidden>:
> Hi all and especially Nicolas,
>
> here is my shotgun approach to fixing the reading of FloatQ. The problem
> lies in Smalltalk's support for arbitrary bases, which does not allow me to
> use the optimized strtod function from the C library.
>
> I decided to write my own tiny floating-point math library (I couldn't
> decide whether using mpf/mpfr was *more* or *less* shotgun) so that I can
> read the FP numbers in 160 bit precision. This is somewhat dual to what the
> Smalltalk code does, which uses fractions and multi-precision integers, and
> it is also how GCC works by the way (though they have more stuff to do
> because of handling denormals, NaNs and infinities).
>
> While I tried it a bit, there might be bugs, so I ask you all to figure out
> some stress tests. These are needed because at some point all floats were
> returned multiplied by 2 :-) and "make" still built... I tried on the ones
> from http://smalltalk.gnu.org/project/issue/313, as well as a few others
> like 1q3000/1q2999 or 3.6451995318824746025q-4951 (FloatQ fmin), and they
> seem to work. Ideas on how to incorporate these into floatmath.st as
> portably as possible are also welcome.
>
> The code is already in git.
>
> Paolo
>