I want to generate a bunch of uniformly distributed non-negative integers in a specified range. The guts of my program look like this:
sub main { if (@ARGV < 3) { USAGE: print STDERR ("Usage: $0 low high samples [seed]\n"); exit 1; } my ($lo, $hi, $samples, $seed) = @ARGV; goto USAGE if ($lo > $hi || $samples <= 0); $seed = srand() unless (defined($seed)); srand($seed); my $range = $hi - $lo + 1; while ($samples-- > 0) { printf("%d\n", $lo + int(rand($range))); } } main();
And the code works just fine for run-of-the-mill arguments. But I am a bit of a nut about avoiding unwanted surprises. If somebody supplies a high that is too large to fit in an integer, the program may not do what they intend. Here are some snippets from a debugging session on my PC.
DB<151> say ~0 18446744073709551615 DB<152> say "of course" if (~0 > 18446744073709551614) of course DB<153> say "of course" if (18446744073709551616 > ~0) DB<154> say 18446744073709551616 1.84467440737096e+19
I'd like to catch any case where the arguments are too big to fit in an integer. I can, and probably will, do this using Math::BigInt, but this seems like using a pile driver to crack a peanut. I could, in fact, use Math::BigInt throughout, but far downstream, I want to pack the integers into compact BigEndian numbers, so it's better for me to enforce acceptable values as early as possible.
Is there a simpler way to ensure arguments fit in integers?
In reply to Number too big to fit in integer by jpl
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |