Man, this is weird! I have no idea what's going on
There's a lot to digest, but here's a few pointers that might make things a little easier.
Firstly, prior to perl-5.30.0, perl was prone to assign values to NVs incorrectly - so you can eliminate one source of frustration by not using a perl that's any older than 5.30.0.
(This problem did not afflict quadmath builds ($Config{nvtype} is '__float128').
Secondly, perl's print() function often lies about floating point values.
A good example is:
>perl -le "print 1.4/10;"
0.14
You might therefore deduce that 0.14 == 1.4/10, but you'd be wrong - and perl will happily inform you of that:
>perl -le "print 'wtf' if 0.14 != 1.4/10;"
wtf
IOW, perl knowingly lies, whereas reputable languages like JavaScript, Raku, and Python (to name a few) will truthfully report that 1.4/10 is 0.13999999999999999, and perl will happily confirm the fact:
>perl -le "print 'ok' if 0.13999999999999999 == 1.4/10;"
ok
The problem is that perl takes the correct 17-significant-digit representation and rounds it to a 15-bit-significant-digit number. Therefore, whenever 16 or 17 significant digits are required for correctness, perl fails to deliver.
I can't describe how stupid I think this choice was without resorting to expletives ...
The best you can do with perl is to use printf() to output 17 significant digits.
At least then you'll have a value that will survive the round trip. A perl floating point scalar $nv, survives the round trip if and only if the condition
("$nv" == $nv) is true. (Apart from NaNs of course.)
The other sane thing that JavaScript, Raku and Python (to name a few) do is to display the fewest possible digits needed for the round trip to succeed. (For this they utilize the
ryu algorithm.
OTOH, if you get perl to printf() 17 significant digits (for correctness), you are often displaying more digits than are necessary.
For example:
>perl -le "printf '%.17g', 1e+23"
9.9999999999999992e+22
Sure - that survives the round trip, but so does "1e+23" - and it's "1e+23" that a smart print() implementation provides.
Perl will tell you that the condition
(9.9999999999999992e+22 == 1e+23) is true, so it makes good sense to output the latter (as do JavaScript, Python and Raku).
If you're interested, you can use Math::Ryu's d2s() function to display the value of your perl NVs (doubles) using the minimum number of significant digits that are required for the round trip to succeed. (Just like JavaScript, Raku and Python !!)
HTH.
Cheers,
Rob