P
Peng Yu
Is there a way to get the minimum and maximum float numbers and
integers?
integers?
Is there a way to get the minimum and maximum float numbers and
integers?
Is there a way to get the minimum and maximum float numbers and
integers?
Is there a way to get the minimum and maximum float numbers and
integers?
Is there a way to get the minimum and maximum float numbers and
integers?
Something like this should get you in the range. [...]
printf ("INT: +/- %d\n", sprintf ("%u", -1) / 2);
has a more official counterpart, which was derived from printf(3) andprintf ("FLOAT: +/- %.".$places."e\n", $mant * 10**$exp);
Scary stuff.Something like this should get you in the range. [...]
printf ("INT: +/- %d\n", sprintf ("%u", -1) / 2);
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
I don't know why division by 2 should be any different than >>1.But the following did the trick:
printf ("INT: +/- %d\n", sprintf("%u", -1)>>1);
INT: +/- 9223372036854775807
^^Instead of interpolating "$places", use a * in the format
specification and add $places as an extra argument to printf.
[snip]On 26 jan, 18:52, (e-mail address removed) wrote:
What does
printf "%d", 18446744073709551615;
printf "%d", 18446744073709551615 / 2;
return? It should return:
-1
9223372036854775807
If not, arithmatic operations would be suspect.
Scary stuff.Something like this should get you in the range. [...]
printf ("INT: +/- %d\n", sprintf ("%u", -1) / 2);
This didn't work for me; it printed:
INT: +/- -9223372036854775808
(platform = CYGWIN_NT-5.1 1.7.1(0.218/5/3))
Is this run under Windows XP-64 or 32?
Is 64 bit native in the OS? What perl distribution?
^Replacing it with:
printf ("INT: +/- %d\n", sprintf ("%u", -1) / 2 - 1);
didn't help, surprisingly:
INT: +/- -9223372036854775808
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.But the following did the trick:
printf ("INT: +/- %d\n", sprintf("%u", -1)>>1);
INT: +/- 9223372036854775807
Funny things can happen like the sign bit is duplicated during arithmatic.
Peter said: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).
ITYM: "(-1) >> 1" is the largest signed integer:
0/1/. (a 0-bit, and then as many 1-bits as possible)
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.
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).
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).
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).
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.
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?
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.
Also, I thought cpu's do integer 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).
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.
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.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.