hexfp may lose 1-3 low order bits (most often, 1) #15033
5.22.0, or bleadperl at 0c8adad:
$ ./perl -wle 'print 0xf.ffffffffffffp0'
The thing is, the second one is not an overflow: in the usual 53-bits-mantissa of IEEE doubles, that's exactly 53 bits. The third one has 54, so it correctly is an overflow. The first one is 52 bits, so not an overflow.
I noticed this case while staring for at the code for perl #126582. So the last hexdigit with bits straddling the NV_MANT_DIG (often 53, see above), may or may not lose some of its bits.
Note that this may be argued at least two ways:
(1) if one specifies, say, 0x8, as the last hex digit, one may argue that one still specifies all the four bits, not just the top one.
The code has so far been choosing the interpretation (1), but maybe the (2) makes more sense, because otherwise one may never specify all the 53 bits using the hexdigits, which is unfair the the very common case. (One could only specify up to 52 bits, using 13 hexdigits.) And hexfp is all about being able to specify the fp down to the last bit.
* Jarkko Hietaniemi <firstname.lastname@example.org> [2015-11-07 23:45]:
To the extent that my mathematical reasoning will carry me, there is no
If so, then this is an irksome case, since only the most significant bit
With the less significant bits all being 0, if the most significant bit
However, if the most significant bit is 1 then losing the zero from the
So you can specify a 13th hex digit with no loss of precision, but only
These are options I can think of:
1. Downgrade this case to a warning. Namely, merely warn about an extra
I.e. a 53-bit mantissa 0000000000000 would be silent, 0000000000008
I guess the warning would have to be in a special category of its own
2. Add notation to specify the number of trailing zero bits that should
This would be kinda cryptic and doesn’t seem to have a real upside in
Re-opening, since this case is not clear-cut, as pointed out.
So the commit I made makes the straddling case to warn, *if* they have one-bits beyond the 53th (if speaking about the common IEEE double case). But if there's just the right number of one-bits in the straddling nibble, no warning. (Nothing is erroring.)
But if one then continues to add more nibbles/hexdigits, of any content, the warning will again happen.
I think at least for 5.22.1 (*) the commit I made enhances the situation, since starting warning after the 13th nibble is just silly, the change effectively moved the warning one bit further.
FWIW, I think all this complication argues for officially (for 5.23/24) allowing the accidentally working "binfp", for allowing just the right number of bits. (The "octfp" is another matter, 3 bits presents even worse confusion than 4 bits.)
(*) Steve Hay told me that since these changes are fixing a new feature, they are worthy. (Especially the earlier perl #126582.)
Regarding this: isn't this about whether the conversion is truncating or rounding, and rounding which way? Now it's strictly truncating.
Aristotle Pagaltzis <email@example.com> wrote:
Does this work?
3. Treat all bits of all hex digits at the least significant end as
0x1.123456789abcdP0 # no warning; rightmost bit == 1
That is: the first two examples specify exactly 53 bits after the
This seems consistent with the way we treat high zero bits in octal
$ perl -wE '$_ = "01" . "0" x 20 . "7"; say for $_, sprintf "%#o", eval'
That is: in the first example there, we have 3 bits in the trailing
(Hex integer literals seem to work the same way too, but they don't
* Jarkko Hietaniemi via RT <firstname.lastname@example.org> [2015-11-08 15:35]:
It was only about me conflating things. But my confusion eludes me yet,