Visualworks native Float literal construction (Number>>readFrom:) is broken as all major Smalltalk implementations

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Visualworks native Float literal construction (Number>>readFrom:) is broken as all major Smalltalk implementations

Eliot Miranda-2
FYI... this from comp.lang.smalltalk.dolphin

Agree with Chris:
- my Dolphin implementation of denormalized is wrong (forgotten
bitShift)!
- internal compiler Float literal construction is broken (i already
posted about that)
- denormalized tests were written for Squeak
- asFraction should read asTrueFraction
- tests should better be enhanced by someone else than programmer
(isn't it a base rule of xtrem'programing?)

WARNING: there must also be a pending bug in my Dolphin version of
asFloat because i have this:
Float fminDenormalized asTrueFraction asFloat = Float fminDenormalized.

I guess the logic of my SUnit Tests lead me to a bug masking another
one !

Funnily, the bitShift was present in my bugfree squeak version...
All my apologies to Dolphiners, and many thanks to Chris for finding
this.


Disagree with Chris for trusting VW:
- Visualworks 7.3 fails on evaluating both expressions:
(10.0d0 ** -316).
1.0d-316 asRational.
- Visualworks native Float literal construction (Number>>readFrom:) is
broken as all major Smalltalk implementations: despite having Infinite
precision rationals, you do not obtain nearest Floating point
approximation due to several successive round off errors in algorithm
used.

10.0 ** -316 tries to evaluate (10.0 ** 316) reciprocal, thus fail with
overflow...
Denormalized floating point are tricky beasts...


Chris Uppal a écrit :

> Hi,
>
> I've been trying to work out why some denormalised floats were producing
> different exact string representations in Dolphin vs Java's
> java.math.BigDecimal. After some messing around it turns out to be a bug in
> Float>>asTrueFraction.
>
> At that point I remembered that Nicolas Cellier posted about this (3rd June
> 2006), but it seems that his proposed fix is incomplete, and also investigating
> why his unit tests didn't show that revealed more problems in Dolphin (which
> may not be new -- I can't remember seeing them before, but...)
>
> This is all using either D5.1 pl4, D6.0 pl1, or D6.0 pl2. The results are the
> same in all revisions except where mentioned below.
>
> The problem with Float>>asTrueFraction is (as Nicolas noted) the incorrect
> handling of denormalised floats. The lines
>
> "Add implied leading 1 into fraction"
> fraction := fractionPart bitOr: 16r0010000000000000.
>
> should read:
>
> "Add implied leading 1 into fraction"
> fraction := expPart = 0
> ifTrue: [fractionPart bitShift: 1]
> ifFalse: [fractionPart bitOr: 16r0010000000000000].
>
> (Nicolas's version was similar but didn't have the bit shift in the true
> branch). With that the expression
>
> Float fminDenormalized asTrueFraction = (1 / (1 << 1074))
>
> evaluates to true, which is correct since the minimum denormalised value is
> 2-1074.
>
>
> That suggests that there was something wrong with Nicolas's proposed unit tests
> (I wouldn't keep harping on about Nicolas's post except that OA often adopt
> people's suggested tests at the same time as their suggested fixes). The main
> unit test for Float>>asTrueFraction is to check that
>
> 1.0e-316 asFraction asFloat = 1.0e-316
>
> is true. There's a trivial problem with that in that in Dolphin (unlike Squeak
> where I think Nicolas does more work) Float>>asFraction doesn't invoke
> Float>>asTrueFraction. But changing it to
>
> 1.0e-316 asTrueFraction asFloat = 1.0e-316
>
> doesn't make the test start indicating the failure of the unfixed version of
> #asTrueFraction. That is because the compiler incorrectly parses 1.0e-316 and
> treats it as a synonym for 0.0 rather than as a denormalised value (which is in
> fact several orders of magnitude greater than Float fminDenormalized). The
> expression
>
> (10.0 ** -316)
>
> /does/ produce the correct denormalised Float. So a test for this compiler
> error is that
>
> (10.0 ** -316) = 1.0e-316
>
> should be true (as it is in VW, and as the nearest equivalent is in Squeak).
>
>
> Another related problem is that typing the above (perfectly valid) expression
> into a D6 workspace causes walkbacks because (I guess) some numeric value
> overflows somewhere in the RB's parser and/or Number>>readFrom:
>
> -- chris