# What are the minimum and maximum float numbers and integers?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Is there a way to get the minimum and maximum float numbers and
integers?

perldoc POSIX

## Re: What are the minimum and maximum float numbers and integers?

On 1/25/2010 4:19 PM, Peng Yu wrote:

use warnings;
use strict;

sub min { \$_[\$_[0]>\$_[1]] }
sub max { \$_[\$_[0]<\$_[1]] }

my @a = ( 1, 2, 3 );

my( \$max, \$min ) = (\$a[0])x2;

for( 1 .. \$#a ) {
\$max = max( \$max, \$a[\$_] );
\$min = min( \$min, \$a[\$_] );
}

print "Max is: \$max\n";
print "Min is: \$min\n";

But you probably meant something else.  :-)

--
Brad

## Re: What are the minimum and maximum float numbers and integers?

On 1/25/2010 4:19 PM, Peng Yu wrote:

you mean epsilon and, iirc, omega?

--

"Six by nine. Forty two."
"That's it. That's all there is."
"I always thought something was fundamentally wrong with the universe"

## Re: What are the minimum and maximum float numbers and integers?

Something like this should get you in the range.

-sln

---------------
use strict;
use warnings;

my \$exp = 10;
while (sprintf("%e", 10**\$exp) !~ /inf/i) {
++\$exp;
}
--\$exp;

my \$places = 6;
my \$mant   = 2 - .1;   # Because 2 always overflows

while (sprintf("%e", \$mant * 10**\$exp) =~ /inf/i) {
\$mant /= 1 + 10**(-\$places);
}

printf ("UINT:   %u\n", -1);
printf ("INT:    +/- %d\n", sprintf ("%u", -1) / 2);
printf ("FLOAT:  +/- %.".\$places."e\n", \$mant * 10**\$exp);

__END__

UINT:   4294967295
INT:    +/- 2147483647
FLOAT:  +/- 1.797693e+308

## Re: What are the minimum and maximum float numbers and integers?

On 26 jan, 18:52, s...@netherlands.com wrote:

[...]

This didn't work for me; it printed:
INT:    +/- -9223372036854775808
(platform = CYGWIN_NT-5.1 1.7.1(0.218/5/3))

Replacing it with:
printf ("INT:    +/- %d\n", sprintf ("%u", -1) / 2 - 1);
didn't help, surprisingly:
INT:    +/- -9223372036854775808

But the following did the trick:
printf ("INT:    +/- %d\n", sprintf("%u", -1)>>1);
INT:    +/- 9223372036854775807

As an aside, the format specification with the embedded \$places in the
format, in

has a more official counterpart, which was derived from printf(3) and
also works in C:
printf ("FLOAT:  +/- %.*e\n", \$places, \$mant * 10**\$exp);

Instead of interpolating "\$places", use a * in the format
specification and add \$places as an extra argument to printf.

## Re: What are the minimum and maximum float numbers and integers?

wrote:

Scary stuff.
Is this run under Windows XP-64 or 32?
Is 64 bit native in the OS? What perl distribution?

^
Since this is supposed to be 'unsigned', its not too suprising.

I don't know why division by 2 should be any different than >>1.
Funny things can happen like the sign bit is duplicated during arithmatic.
But thats seems more a consequence for signed types less than the native
machine word (int) of a typed language like C.

Well, if shift right 1 (not division by 2) works for you, then you don't
need the sprintf(), a simple  printf ("INT:    +/- %d\n", -1>>1 );
will do.

What does
printf "%d", 18446744073709551615;
printf "%d", 18446744073709551615 / 2;
return? It should return:
-1
9223372036854775807
If not, arithmatic operations would be suspect.

^^
Thanks.

-sln

## Re: What are the minimum and maximum float numbers and integers?

On Fri, 29 Jan 2010 16:07:45 -0800, sln@netherlands.com wrote:

[snip]

Or, to clarify (at least in your case), arithmatic operations
resulting in or on values outside the range of  (+/-) signed int (machine word).
But Windows-64 will run 32-bit programs with sign emulation. It seems more a
processor feature though.

-sln

## Re: What are the minimum and maximum float numbers and integers?

Because division is always done in floating point arithmetic in Perl.
So the result of (18446744073709551615/2) should be
9223372036854775807.5 - but that isn't representable in a 53 bit
mantissa, so it is rounded to the next representable value which happens
to be 9223372036854775808 (the next lower representable FP value btw is
9223372036854774784, so subtracting any value <= 512 doesn't have any
effect).

If int(18446744073709551615/2) gives you 9223372036854775807 you
probably have compiled perl to use long double arithmetic.

C doesn't define[1] what happens if you right-shift a negative value.

But Perl does, at least if don't "use integer":

|      Note that both "<<" and ">>" in Perl are implemented directly using
|      "<<" and ">>" in C.  If "use integer" (see "Integer Arithmetic") is in
|      force then signed C integers are used, else unsigned C integers are
|      used.
(perldoc perlop)

So (-1 >> 1) uses unsigned integer operations. (unsigned)-1 is
guaranteed to be the largest unsigned integer, so (-1 >> 1) is half of
that which is half the largest signed integer (unless there are unused
bits in the implementation, which C allows, but that's exceedingly
rare).

hp

[1] Although I think it's implementation-defined, not undefined.

## Re: What are the minimum and maximum float numbers and integers?

Peter J. Holzer wrote:

ITYM: "(-1) >> 1" is the largest signed integer: 0/1/.
(a 0-bit, and then as many 1-bits as possible)

--
Ruud

## Re: What are the minimum and maximum float numbers and integers?

Unary - binds closer than binary >>, so (-1 >> 1) is the same as
((-1) >> 1). So I don't see how that differs from what I wrote.

Yes.

hp

## Re: What are the minimum and maximum float numbers and integers?

Ah, I see it now: "half the largest signed integer" should of course
have read "the largest signed integer". Somehow I duplicated the "half".

hp

## Re: What are the minimum and maximum float numbers and integers?

Doh, what was I thinking. Of course.

In C, the value passed to printf using formatter %d must be an integer (signed
or not).
So the result of the division, a float, must be coerced to integer:
printf ("%d", (int)(18446744073709551615/2) );
Does Perl do this coersion in C or does it do its own rounding then chopping via
custom methods?

I guess the IEEE 87 standard is 53 bit mantissa so it can't handle a 64 bit
(-1) u_integer division, but would handle 32 bit u_integers. That explains
how   printf ("%d", 4294967295/2);  works, but how can the previous poster's
64 bit result be  -9223372036854775808 which is almost correct?
If his Perl is using long-double shouldn't this extend the mantissa past 53 bits?

As an aside, I wonder if Perl is sometimes compiled to take advantage of
faster SSE-2 64-bit in lieu of precision 80 bit. I know when I compile C++
I don't enable support for those instructions, and usually select precision
over speed.

Also, I thought cpu's do integer arithmetic +-/*

Thanks.

-sln

## Re: What are the minimum and maximum float numbers and integers?

Since perl is written in C, it obviously does it "in C", but how exactly
the conversion is done I don't know (and I'm currently too lazy to check
the source). My guess is that it is a simple cast to unsigned int:

printf "%d\n", 1E100

prints -1 on my systems which is the same as

printf("%d\n", (unsigned int)1E100);

in C. Since this result is arguably wrong I wouldn't rely on it -
somebody might someday fix it.

I think I explained that. What wasn't clear about the explanation?

The gcc manual says about SSE instructions:

|  For the x86-64 compiler, these extensions are enabled by default.

So, it you are using perl on a 64 bit Linux system, it will (almost
certainly) use SSE instructions. The speed advantage is probably small -
interpreter overhead is likely to be much greater than the time actually
spent in FP arithmetic.

CPUs do what they are told.

hp

## Re: What are the minimum and maximum float numbers and integers?

Perl calls SvIV (or SvUV for %u) which is the normal make-this-scalar-a-
signed-int operation. AFAICT it does this first for all of %d, %hd, %sd,
%ld and %qd, followed by casting to the appropriate C type, so if your
perl is build with 32-bit IVs you can't print a float greater than 2^31
using %d even if Configure found a 64-bit Quad_t type.

I have to say I'm surprised that SvIV ever does overflow to -1, but it
appears it does:

~% perl -Minteger -E'say for 1E100, 0+1E100'
1e+100
-1
~%

I might consider this a bug, since it's not what C does with

(int)(1e100)

but rather what C does with

(int)(unsigned int)(1e100)

I'm not sure going NV->IV via UV is helpful in this case.

Ben

## Re: What are the minimum and maximum float numbers and integers?

On 30/01/2010 10:44, Peter J. Holzer wrote:

Even if there are padding bits, the C Standard defines the unsigned
right-shift E1 >> E2 as the integral part of E1 / (2**E2). The result
must be a valid unsigned integer. As a result, padding bits cannot
change the meaning of a bitshift operation.

Phil

## Re: What are the minimum and maximum float numbers and integers?

Yes but not necessarily a valid signed integer. More specifically

UINT_MAX / 2 == INT_MAX

doesn't have to be true. An unsigned int may use more or less bits for
representing the value than a signed int.

This isn't about the meaning but about the result. UINT_MAX >> 2 is
always the same as UINT_MAX / 2, but this is not necessarily the same as
INT_MAX.

hp

## Re: What are the minimum and maximum float numbers and integers?

On 30/01/2010 21:52, Peter J. Holzer wrote:

That's a very good point. I guess this is why C provides those constants
in the first place :)

Phil