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