laziness, impatience, and hubris PerlMonks

### Re^3: Infinity and Inf? (MAX_INT)

by LanX (Bishop)
 on Sep 01, 2010 at 12:58 UTC ( #858332=note: print w/replies, xml ) Need Help??

in reply to Re^2: Infinity and Inf?

> Or with less obfuscation ...

> use constant MAXINT => ~0; Not true on my box..

```  DB<1> print ~0
4294967295
DB<2> print ~0+1
4294967296
DB<3> print ~0+2
4294967297
...
DB<12> print ~0*2**18
1.12589990658048e+15
...
DB<15> print ~0*2**17
562949953290240
...
DB<33> p unpack('J', pack('j', -1));
4294967295
DB<34> p 0+sprintf('%u', -1);
4294967295
The MAX_INT is somewhere between 2**49 and 2**50!

UPDATE:

```  DB<81> p 999999999999999+1
1e+15
DB<82> p 999999999999998+1
999999999999999
DB<83> p 999999999999998+2
1e+15
DB<84> p 999999999999998+2-1
999999999999999
DB<85> p 1e+15-1
999999999999999
Seems to depend on the decimal representation of the mantissa of the floating point arithmetics.

UPDATE:

to be more precise, integers still work internally for higher numbers even if they can't be represented.

```  DB<88> p 999999999999998+4-5
999999999999997
...
DB<96> p 999999999999999+2**52 -2**52
999999999999999
DB<97> p 999999999999999+2**53 -2**53
1e+15

UPDATE

Last but not least
```  DB<32> \$x=0;for(1..2**31) {print;last if \$x++>5}
Range iterator outside integer range at (eval 36)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.

DB<33> \$x=0;for(1..2**30) {print;last if \$x++>5}
1234567

DB<34> \$x=0;for(1..~0) {print;last if \$x++>5}
Range iterator outside integer range at (eval 45)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.
The range operator seems only to be implemented for signed 32bits integers...so MAX_INT wouldn't even help here!
```  DB<46> \$x=0;for(1..2**31-2) {print;last if \$x++>5}
1234567
DB<47> \$x=0;for(1..2**31-1) {print;last if \$x++>5}
Range iterator outside integer range at (eval 51)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.

Cheers Rolf

Replies are listed 'Best First'.
Re^4: Infinity and Inf? (MAX_INT)
by ikegami (Pope) on Sep 01, 2010 at 15:51 UTC

You are mistaken. We were talking about the maximum value that can be used in a range, and it's not even close to 2**50.

(By the way, the largest positive integer that can be stored without loss of precision in a double-precision float is 2**53.)

I was wrong too, though. I thought it was the largest native unsigned integer, but it's the largest native signed integer.

```\$ perl -e'1 for 2147483647..2147483647'

\$ perl -e'1 for 2147483647..2147483648'
Range iterator outside integer range at -e line 1.

That limit be obtained using the following:

```use constant MAX_RANGE => (~0)>>1;
> You are mistaken.

> That limit be obtained using the following:

I question these design decisions forcing the user to care about such implementation details.

From a higher language perspective it doesn't make sense why a range operator within a for(..){} can't iterate thru the same spectrum like a while(\$x++){ } can do.

IMHO the cleanest syntax would be allowing to use Inf which is automatically translated to whatever maximum the current implementation of an operator can handle.

Cheers Rolf

I question these design decisions forcing the user to care about such implementation details.

Which users are those? Very few will ever needed to iterate over numbers greater than 2,147,483,648, and very few will ever need to iterate over numbers greater than 9,223,372,036,854,775,807 (64-bit builds).

It's a compromise between resources and utility. Only using integers internally is faster, requires less memory and requires less code than supporting both integers and floats.

the cleanest syntax would be allowing to use Inf

If we pretend that for to take a lazy list, you'll complain that it doesn't make sense for map not to, from a higher language perspective.

Mind you, I think for (\$x..Inf) has merit.

for(..){} can't iterate thru the same spectrum like a while(\$x++){ } can do.

If you think the range op has a seemingly arbitrary limit, you should see ++'s! For example, 1e16 to 1e16 is ok, but 1e16 to 1e16+1 isn't.

```\$ perl -E'for (my \$_ = 1e16; ; ++\$_) { say }'
1e16
1e16
1e16
1e16
...

Update: Mixed \$x and \$_ in last snippet. Fixed.

Re^4: Infinity and Inf? (MAX_INT)
by BrowserUk (Pope) on Sep 01, 2010 at 14:53 UTC
The range operator seems only to be implemented for signed 32bits integers

On a 64-bit perl, it handles integers greater than 32-bit.

Though there appears to be a bug. Somewhere in between, the 64-bit integers are being transitioned through an NV (double) before being converted back to integers for the iterator it seems:

```for my \$p ( 32 .. 64 ) {
my \$n = 2**\$p;
printf "\n\$p";
printf " \$_" for \$n .. \$n + 2;
};;

32 4294967296 4294967297 4294967298
33 8589934592 8589934593 8589934594
34 17179869184 17179869185 17179869186
35 34359738368 34359738369 34359738370
36 68719476736 68719476737 68719476738
37 137438953472 137438953473 137438953474
38 274877906944 274877906945 274877906946
39 549755813888 549755813889 549755813890
40 1099511627776 1099511627777 1099511627778
41 2199023255552 2199023255553 2199023255554
42 4398046511104 4398046511105 4398046511106
43 8796093022208 8796093022209 8796093022210
44 17592186044416 17592186044417 17592186044418
45 35184372088832 35184372088833 35184372088834
46 70368744177664 70368744177665 70368744177666
47 140737488355328 140737488355329 140737488355330
48 281474976710656 281474976710657 281474976710658
49 562949953421312 562949953421313 562949953421314
50 1125899906842624 1125899906842625 1125899906842626
51 2251799813685248 2251799813685249 2251799813685250
52 4503599627370496 4503599627370497 4503599627370498
53 9007199254740992 9007199254740993 9007199254740994
54 18014398509481984
55 36028797018963968
56 72057594037927936
57 144115188075855872
58 288230376151711744
59 576460752303423488
60 1152921504606846976
61 2305843009213693952
62 4611686018427387904
63[Range iterator outside integer range at (eval 21) line 1, <STDIN> l
+ine 17.

Good luck in trying to track that bug down :)

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Though there appears to be a bug. Somewhere in between, the 64-bit integers are being transitioned through an NV (double) before being converted back to integers for the iterator it seems:

There is code that assumes NV vars can handle larger integers than IV and UV vars can. That's not the case for all builds anymore, so these builds have unexpected overflow conditions.

(BrowserUK probably knows that, but I thought someone else might be curious.)

Thanks but thats not my problem, its the break of symmetry between .. and ++ which "bugs" me!

IMHO it doesn't make sense to restrict the rangeoperator to signed integers when floats can still represent bigger integers (which are perfectly transparent when used with arithmetic operators).

Cheers Rolf

IMHO it doesn't make sense to restrict the rangeoperator to signed integers when floats can still represent bigger integers

I can sort of sympathise with that.

But for counterpoint, does it make sense to restrict the iteration of a float iterator to unitary integer increments?

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re^4: Infinity and Inf? (MAX_INT)
by BrowserUk (Pope) on Sep 01, 2010 at 13:16 UTC
The MAX_INT is somewhere between 2**49 and 2**50!

Your test is flawed. The maximum integer that can be accurately stored in a NV is 2**53 = 9007199254740992.

```printf "%.15f\n", 2**53;;
9007199254740992.000000000000000

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

see my updates in the meantime!

Cheers Rolf

Your test is still flawed because MAX_INT is not MAX_UINT nor is it "the maximum of the range of integers that can be exactly stored in an NV". ~0 is MAX_UINT. MAX_INT is int(~0/2), which is 32 bits on some builds of Perl but not on others. See "IV".

```for(  my \$i= \$start;  1;  \$i++  )

Update: And it is usually spelt INT_MAX, it seems.

- tye

Create A New User
Node Status?
node history
Node Type: note [id://858332]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2017-11-19 00:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In order to be able to say "I know Perl", you must have:

Results (278 votes). Check out past polls.

Notices?