[squeak-dev] The Trunk: Kernel-nice.1276.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Oct 18 11:21:46 UTC 2019


Hmm stupid, it's sign not signBit!
I now also broke the positive ones :(
I delete this version and retry...

Le ven. 18 oct. 2019 à 13:13, <commits at source.squeak.org> a écrit :

> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-nice.1276.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-nice.1276
> Author: nice
> Time: 18 October 2019, 1:13:01.217084 pm
> UUID: 52c1774b-4ff6-40f3-a575-f53af8746515
> Ancestors: Kernel-mt.1275
>
> Fix my recent bug in Integer>>asFloat.
>
> Explanations: with introduction of digitsAsFloat, I removed implementation
> of LargeNegativeInteger>>asFloat because all the involved bitOps in
> superclass (LargePositiveInteger) operate on magnitude and thus work for
> negative too (bitShiftMagnitude: and anyBitOfMagnitudeFrom:to:).
>
> Err... All operations but one:
>         mantissa := mantissa + 1.
>
> Unfortunately, this was not caught by our tests...
> We all know that 100% coverage does not mean 100% correct.
> But 100% coverage of a method also does not mean 100% coverage for every
> possible subclass!
>
> =============== Diff against Kernel-mt.1275 ===============
>
> Item was changed:
>   ----- Method: LargePositiveInteger>>asFloat (in category 'converting')
> -----
>   asFloat
>         "Answer a Float that best approximates the value of the receiver.
>         This algorithm is optimized to process only the significant digits
> of a LargeInteger.
>         And it does honour IEEE 754 round to nearest even mode in case of
> excess precision (see details below)."
>
>         "How numbers are rounded in IEEE 754 default rounding mode:
> +       A shift is applied so that the highest 53 bits are placed before
> the floating point to form a significand.
> -       A shift is applied so that the highest 53 bits are placed before
> the floating point to form a mantissa.
>         The trailing bits form the fraction part placed after the floating
> point.
>         This fractional number must be rounded to the nearest integer.
>         If fraction part is 2r0.1, exactly between two consecutive
> integers, there is a tie.
>         The nearest even integer is chosen in this case.
> +       Examples (First 52bits of significand are omitted for brevity):
> -       Examples (First 52bits of mantissa are omitted for brevity):
>         2r0.00001 is rounded downward to 2r0
>         2r1.00001 is rounded downward to 2r1
>         2r0.1 is a tie and rounded to 2r0 (nearest even)
>         2r1.1 is a tie and rounded to 2r10 (nearest even)
>         2r0.10001 is rounded upward to 2r1
>         2r1.10001 is rounded upward to 2r10
> +       Thus, if the next bit after floating point is 0, the significand
> is left unchanged.
> +       If next bit after floating point is 1, an odd significand is
> always rounded upper.
> +       An even significand is rounded upper only if the fraction part is
> not a tie."
> -       Thus, if the next bit after floating point is 0, the mantissa is
> left unchanged.
> -       If next bit after floating point is 1, an odd mantissa is always
> rounded upper.
> -       An even mantissa is rounded upper only if the fraction part is not
> a tie."
>
>         "Algorihm details:
>         The floating point hardware can perform the rounding correctly
> with several excess bits as long as there is a single inexact operation.
>         Note 1: the inexact flag in floating point hardware must not be
> trusted because in some cases the operations would be exact but would not
> take into account some bits that were truncated before the Floating point
> operations.
>         Note 2: the floating point hardware is presumed configured in
> default rounding mode."
>
> +       | significand shift excess |
> -       | mantissa shift excess |
>
> +       "Check how many bits excess the maximum precision of a Float
> significand."
> -       "Check how many bits excess the maximum precision of a Float
> mantissa."
>         excess := self highBitOfMagnitude - Float precision.
>         excess > 7
> -               ifTrue:
> -                       ["Remove the excess bits but seven."
> -                       mantissa := self bitShiftMagnitude: 7 - excess.
> -                       shift := excess - 7.
> -                       "An even mantissa with a single excess bit
> immediately following would be truncated.
> -                       But this would not be correct if above shift has
> truncated some extra bits.
> -                       Check this case, and round excess bits upper
> manually."
> -                       ((mantissa digitAt: 1) = 2r01000000 and: [self
> anyBitOfMagnitudeFrom: 1 to: shift])
> -                               ifTrue: [mantissa := mantissa + 1]]
>                 ifFalse:
> +                       ["We can use naive digit by digit conversion
> because there will be a single inexact round off at last iteration.
> +                       But the nice thing is that Float precision + 7
> excess bits = 60 which fit in a SmallInteger in Spur64.
> +                       So the best to do is to delegate this final
> operation"
> +                       ^self digitsAsFloat ].
> -                       [mantissa := self.
> -                       shift := 0].
>
> +       "Remove the excess bits but seven."
> +       significand := self bitShiftMagnitude: 7 - excess.
> +       shift := excess - 7.
> +       "An even significand with a single excess bit immediately
> following would be truncated.
> +       But this would not be correct if above shift has truncated some
> extra bits.
> +       Check this case, and move an extra bit to the last significand
> digit."
> +       ((significand digitAt: 1) = 2r01000000 and: [self
> anyBitOfMagnitudeFrom: 1 to: shift])
> +               ifTrue: [significand := significand + self signBit].
> +
> +       ^significand digitsAsFloat timesTwoPower: shift.!
> -       "We can use naive digit by digit conversion because there will be
> a single inexact round off at last iteration.
> -       But the nice thing is that Float precision + 7 excess bits = 60
> which fit in a SmallInteger in Spur64.
> -       So the best to do is to delegate this final operation"
> -       ^mantissa digitsAsFloat timesTwoPower: shift.!
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20191018/8c05677d/attachment.html>


More information about the Squeak-dev mailing list