in reply to Non-integer print output???
Why not? Exponentiation is an operation done using floating point numbers. And there's no point in checking if the number is an integer within range of the user's IV or UV types, and converting it to those from the NV.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Non-integer print output???
by syphilis (Archbishop) on Sep 11, 2021 at 16:16 UTC | |
I don't think it's quite that simple. Consider the example of 2** 50 provided by the OP - where the result was given as 1.12589990684262e+15. That particular result is absolute rubbish. The correct figure is 1125899906842624.0 (which is a different value, yet one that is exactly representable inside that perl's NV) : Why are we so ready to settle for a half-arsed floating point approximation when an exact floating point (or integer) representation is available ? Also consider that, on a perl whose ivsize is 8 && whose nvsize is 8, you will be told that 3 ** 40 (which equates to less than ~0) is 1.21576654590569e+19. This is a completely different value to the exact 12157665459056928801, which would be presented if perl DWIMmed by performing integer exponentiation. And perl prides itself on DWIMming .... ?? Cheers, Rob | [reply] [d/l] [select] |
by ikegami (Patriarch) on Sep 12, 2021 at 14:35 UTC | |
Not at all. In fact, your snippet proves that the correct result is returned. You think the incorrect result is returned because you incorrectly assume print doesn't perform any rounding.
It's not an approximation. The result is 100% exact in this case. (Powers of two literally require only 1 bit of precision, and that bit isn't even stored.) There are cases where exponentiation could produce more accurate numbers using ints than floats on a build with 64 bit ints. But this is eclipsed by the number of cases that are more precise using floats (e.g. 2**0.5), and it's also eclipsed by the number of cases that are only possible using floats (e.g. 2**65). It looks like you are raising your own question about why scientific notation is used by print or why it rounds, but the question asked was about why exponentiation returns "a float instead of a 64-bit number". That has nothing to do with how print stringifies floats. Sure, that could be improved, but that's a different question. Upd: Rewritten | [reply] |
by syphilis (Archbishop) on Sep 13, 2021 at 10:32 UTC | |
Of course the correct result is returned. The "rubbish" part is for the print() function to display that result as 1.12589990684262e+15. The returned result is not 1.12589990684262e+15: It's not an approximation. Well, that depends upon what "it" is actually referring to. Certainly, the returned value is not an approximation. But the value delivered by the print() function is most definitely an approximation. In floating point notation, the exact correct presentation is 1.125899906842624e+15.
I'm sure you're already aware of all of this. I can see that I could have been clearer in my last post. It's a PITA having to continually clarify whether one is talking about the the interpolated value (ie the value presented by the print function) or the actual returned value - and I might have got a bit lax about making the distinction. By contrast, print() always provides accuracy in the values being displayed for IVs - so it's a pity that perl doesn't DWIM by performing integer exponentiation on positive integer operands (and return an IV) whenever integer overflow is not an issue. Or, alternatively, perl could start interpolating NVs in a sane way. (That's not an unreasonable expectation - python does it; raku does it.) On perls where IVSIZE and NVSIZE are 8, I'm perpetually astounded that we allow (eg) 1 << 50 and 2 ** 50 to be interpolated to different values. Cheers, Rob PS In some rare moments of prolonged high-energy I did submit a pre-RFC post to p5p about these issues with NV interpolation. But I haven't managed to yet summons the energy to deal with the follow up actions requested in response to that post. As I've mentioned there, my Math::MPFR module provides me with the sane behaviour I seek (coutesty of its nvtoa() function), and it's far easier for me to use that whenever I want sane behaviour, rather than to get too fussed about coming up with an RFC that might then never be acted upon anyway. | [reply] [d/l] [select] |