If perl's abstraction of numbers isn't good enough for you, it's easy enough to fix. use bignum;.
'Oddness' is an inherently integer concept and a boolean condition. Using an inherently non-integer, non-boolean operator to test for an inherently integer, boolean condition is just plain wrong!
This I entirely, 100% agree with. Absolutely. However, I think you're getting a bit paranoid here. In my definition of oddness, I stipulated that it was confined to the set of integers - so talking about floating point concerns seems a bit orthogonal to that question. So, in the range of integers (from -inf to +inf), perl can't quite handle 'em all. But, that said, the concept itself is simple: an integer is odd iff it is not even. An integer is even iff its remainder when divided by two is zero. Thus, the simple boolean statement of $x % 2 != 0 (which is just a minor simplification from the more literal !($x % 2 == 0)) Or, a simpler definition of oddness is an integer which is not evenly divisible by two - which gives us the same boolean test. Then, when dealing with huge numbers, insert the bignum pragma, and you're done. A bit slow, perhaps, but accurate.
As to your comments on bitwise operations on non-integral reals, I think that's just reminiscent of C where some people try to do that and think they're being smart. Instead of testing "if (x < 0)", they try to test the negative bit in the double, wherever that is. (Then they get hurt in a similar way when they somehow get a "negative zero".) Personally, I wouldn't mind a warning from perl's runtime for it - bit twiddling with reals is probably not what you were intending to do.
| [reply] [d/l] [select] |
If perl's abstraction of numbers isn't good enough for you,
It's not "for me", it's "for my application".
it's easy enough to fix. use bignum;.
Ah! But ... if that's your answer to future proofing against speculative what-ifs
- You either
- need to use bignum; in every program always; or
Which is going to make your programs crawl when it is completely unnecessary 99.99% of the time.
- selectively choose when to use bignum;
Which is no different to using integers, and integer operators selectively; knowingly.
You cannot have it both ways. What's good for the goose is good for the gander.
- You completely missed my point about sum 1 .. 2**30;, but that's my fault for not making it clear.
Perl's reals are perfectly capable of holding sum 1 .. 2**30. There is no need for bignum.
use List::Util qw[ sum ];
$n = 576460752840294400;
printf "%20.f\n", $n;;
576460752840294400
The problem is that trying to compute it (or even 1sum 1 .. 2**26 with List::Util::sum() crashes perl!
It's a bug. But so is 99_999_999 & 1. No difference. Neither will allow you to future proof your application against speculative integer math that grows beyond certain limits.
Then, when dealing with huge numbers, insert the bignum pragma, and you're done. A bit slow, perhaps, but accurate.
When dealing with non-IV/UV values, don't use integer operations, and your done.
You cannot have it both ways. What's good for the goose is good for the gander.
I think you're getting a bit paranoid here. In my definition of oddness, I stipulated that it was confined to the set of integers - so talking about floating point concerns seems a bit orthogonal to that question
I'm getting paranoid?.
I was responding to your citing of tye (getting paranoid) about what happens when using & 1 on integers that have been promoted to reals through growing beyond the integer range.
I was pointing out that using floats to hold oversized integers is at best a hack, and at worst dangerous because if you attempt to use integer operations on integers stored as floats, perl does very strange things.
I was also pointing out that adding a second hack to work around the limitations of the first hack--using % 2 to test for oddness--was compounding a problem and producing another, worse problem. Especially, if you compound that by using if( $n % 2 ) ... instead of the full if( $n % 2 == 0 )....
And that even if you do you the latter, you're still not "future proof", when your integers move beyond the range for which your reals are capable of representing integers accurately.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
use Math::BigInt;
my $sum = Math::BigInt->new(2);
$sum->bpow(30);
$sum = ($sum * $sum + $sum) / 2;
print $sum;
__DATA__
576460752840294400
This is mostly in jest but it does illustrate that programmer knowledge of the specific task at hand is more valuable then generalizations. There are similar formulas for summing just the odd or even numbers from 1 .. N as well.
| [reply] [d/l] [select] |
$n = 576460752840294400;
printf "%20.f\n", $n;;
576460752840294400
The problem is that (on my system),
use List::Util qw[ sum };
$n = sum 1 .. 2**26;
crashes Perl.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
| [reply] |