Why "use integer" makes no difference, IMO, is that Perl recognises the example expression as floating point
Yes, I think it's likely that perl does precisely that ... but it's rather simplistic of perl to assume that the value should be represented as an NV (double) just because scientific notation was used. (Of course, on a 32-bit build of perl it won't matter, but on a 'use64bitint' build of perl it's not a very bright thing to do, imo - unless 'uselongdouble' is also in place as ysth recommended - in which case it'll be ok).
As tye suggested, I think there's an element of "history" here. (I referred to the same thing in one of my posts in this thread as "32-bit legacy".) No matter what you call it, I don't think it's a very convincing excuse.
tye also referred to "perl opcodes" - and, I must confess, that I have no idea how that impacts upon perl's capacity to get it right.
My hunch (and it's no more than that) is that there's a lack of interest in getting perl to do the right thing wrt 'use64bitint' builds ... and, furthermore, that's the main reason that perl doesn't do the right thing.
I mean, how hard would it be for perl to determine that 1.44115188075868217e17 represents an integer (especially with use integer;), stick that value in an IV slot (given that it fits there), and turn on the IOK flag ? I don't know the answer to that question, btw ... but Shirley that wouldn't be all that difficult for the current perl pumpkings to implement. (As always, I stand to be corrected.)
Anyway, perl's one redeeming feature is that it at least gives one the tools to fix the problems it creates :-)
Cheers, Rob | [reply] [d/l] [select] |
You've got one case that isn't done as well as you'd like. Somebody could spend some time doing some dodgy hack to try to take care of this one case (have you started writing this patch? -- I don't believe your assessment of the difficulty involved if you haven't). Then you'd be left to whine about a ton of other cases that you just haven't run into yet.
So what's your brilliant, simple way to just know that 1.4...e17 (and every other numeric literal) fits in this perl's version of IV "better" than in this perl's version of NV? Are you going add comparisons/tests to determine this each time Perl runs into a literal? And then, for each of the new cases you eventually run into, add more comparisons/tests again, basically boiling down to doing every calculation twice and then doing extra work to determine whether the NV or IV result is "better"?
Stop looking at just your one pet case and try to look at the larger problem. Predicting whether a result would be better represented in an IV or an NV isn't a simple problem, whether you'd like to think it is or not... except in the excellent case of making the NVs able to hold any IV, which is a route open to you.
So your argument boils down to not really understanding how to do it, not being interested in doing it yourself, rather blithely assuming that it isn't difficult for someone else to do for you, complaining because they aren't running off to do it, and not offering any response as to why you aren't fixing the problem yourself by just changing one more option in your build. Can you see how that might not be persuasive to everyone? :)
| [reply] |
and not offering any response as to why you aren't fixing the problem yourself by just changing one more option in your build
I was thinking more along the lines of how to write (portable) code that works on those builds of perl that were built with use64bitint, but no long doubles - rather than simply how to get the code to work on my own machine.
(As an aside, I don't know how much success I'd have in building my own perl with that change to just "one more option" - especially given that I'm on Windows.)
I'm sure I can eventually adapt my thinking and coding practices to handle these curly situations correctly.
Thanks for your thoughts.
Cheers, Rob
| [reply] |
"use integer;" works on fixed point values INDEPENDENTLY of how many bits the machine has or how many bits are needed to represent a given value.
Limiting it to fixed point assures that the functionality is injective. What you are asking for would downgrade it to non-injective, i.e. would make it work and not work according to a bits-needed comparison between a) the value being operated on and b) the size of the registers in the machine.
I have meanwhile thought of another way to get what you want: sprintf. If the number is floating point, it internally uses the C sprintf, thereby achieving much high performance for your requirement than changing the meaning of use integer ever could anyway.
__________________________________________________________________________________
^M Free your mind!
| [reply] |
I have meanwhile thought of another way to get what you want: sprintf
I don't quite follow. At its simplest, what I want is to have a string like '1.44115188075868217e17' converted to the numeric value 144115188075868217 on a use64bitint build of perl that doesn't have long doubles. I can't see a way of doing that using (s)printf. I find that printf "%d", '1.44115188075868217e17' produces 144115188075868224. Sorry if I've missed the point. (I do that sometimes :-)
By looking at the sign, mantissa, and exponent it's not all that difficult to get the required result - and that's pretty much how I'll be doing it.
Thanks Moron.
Cheers, Rob
| [reply] [d/l] [select] |