From: Peter J. Holzer on
On 2010-05-20 14:58, Ilya Zakharevich <nospam-abuse(a)ilyaz.org> wrote:
> On 2010-05-19, Ben Morrow <ben(a)morrow.me.uk> wrote:
>> Can you give an example of things not behaving as expected?
>
> I was presuming that such things happens left and right, so I did not
> try to remember the problems people were reporting. But I may try to guess...
>
> And: I do not have Perl with 64-bit IV AND 64-bit NV around, so all
> this is just a conjecture: I expect the the following things to break:
>
> rounding by int($n + 0.t);

what is $n here (conceptually)? An integer? Then it doesn't make sense
to round it. A floating point value? Then adding 0.5 doesn't change the
type and whether IVs are 32 bit or 64 bit doesn't matter.

> $x + 0.5 >= $x

Again, this is already "broken" (i.e., a false assumption) on large
numbers, making IVs 64 bit doesn't change that.

A better example would be where something like

$large_even_integer/2

where the result is exact in integer arithmetic but must be rounded in
FP arithmetic. However, perl (at least since 5.8.8) does the right thing
here: The result is an IV with the exact result. (how does it do this?)

hp

From: Ben Morrow on

Quoth "Peter J. Holzer" <hjp-usenet2(a)hjp.at>:
>
> A better example would be where something like
>
> $large_even_integer/2
>
> where the result is exact in integer arithmetic but must be rounded in
> FP arithmetic. However, perl (at least since 5.8.8) does the right thing
> here: The result is an IV with the exact result. (how does it do this?)

The code is in pp_divide in pp.c. Basically, if there is a chance the
division will produce an exact integer result that can't be represented
as a float, the code will

- make both numbers positive
- do the division in unsigned ints
- if the result was exact (checked with an unsigned-int multiply)
- return an unsigned int if the result should be positive,
- return a (negated) signed int if the result should be negative
and it fits,
- otherwise cast the int to a float and return the negation of
that (which may be inaccurate, but that can't be helped);
- else
- do a floating-point division

Ben

From: sln on
On Sat, 22 May 2010 10:57:53 +0200, "Peter J. Holzer" <hjp-usenet2(a)hjp.at> wrote:

>On 2010-05-21 16:24, sln(a)netherlands.com <sln(a)netherlands.com> wrote:
>> On Thu, 20 May 2010 13:02:08 +0200, "Peter J. Holzer" <hjp-usenet2(a)hjp.at> wrote:
>>>On 2010-05-19 23:56, sln(a)netherlands.com <sln(a)netherlands.com> wrote:
>>>> On Wed, 19 May 2010 23:44:50 +0100, Ben Morrow <ben(a)morrow.me.uk> wrote:
>>>>>and a C program the does the same operations on a signed 32bit integer
>>>> ^^ .........^^
>>>> This is redundant. There is only unsigned and int.
>>>
>>>Wrong. "integer" is not the same as "int". The C standard knows five
>>>standard signed integer types and six standard unsigned integer types.
>>>And "int" and "unsigned" are just abbreviations of "signed int" and
>>>"unsigned int", respectively.
>>
>> Technically there are no "integer types", they are integral types.
>
>Please read the standard.
>
Integer is what it is, a single whole number from the set of all whole numbers.
There is no type of integer. There are subsets, they are called integral types
in computing science.

If the phrase is loosely used, thats a shame. C/C++ standard and all references to
it use integral types as classifier of the subsets.

-sln
From: Ilya Zakharevich on
On 2010-05-22, Peter J. Holzer <hjp-usenet2(a)hjp.at> wrote:
>> And: I do not have Perl with 64-bit IV AND 64-bit NV around, so all
>> this is just a conjecture: I expect the the following things to break:
>>
>> rounding by int($n + 0.t);

> what is $n here (conceptually)?

A number.

> An integer? Then it doesn't make sense to round it.

Why? I can round 3 without any problem here...

> A floating point value? Then adding 0.5 doesn't change the
> type and whether IVs are 32 bit or 64 bit doesn't matter.

perldoc perlnumber

>> $x + 0.5 >= $x

> Again, this is already "broken" (i.e., a false assumption) on large
> numbers, making IVs 64 bit doesn't change that.

??? Are you sure you know what you are talking about?

Yours,
Ilya
From: Peter J. Holzer on
On 2010-05-23 23:08, Ilya Zakharevich <nospam-abuse(a)ilyaz.org> wrote:
> On 2010-05-22, Peter J. Holzer <hjp-usenet2(a)hjp.at> wrote:
>>> And: I do not have Perl with 64-bit IV AND 64-bit NV around, so all
>>> this is just a conjecture: I expect the the following things to break:
>>>
>>> rounding by int($n + 0.t);
>
>> what is $n here (conceptually)?
>
> A number.

Not specific enough.


>> An integer? Then it doesn't make sense to round it.
>
> Why? I can round 3 without any problem here...

Because it is already an integer. Rounding it is useless since it is
guarantueed to give you the same value (unless you want to round to the
nearest integer representable as an FP value, then the expression does
what you want).



>> A floating point value? Then adding 0.5 doesn't change the
>> type and whether IVs are 32 bit or 64 bit doesn't matter.
>
> perldoc perlnumber

Please be more specific.


>>> $x + 0.5 >= $x
>
>> Again, this is already "broken" (i.e., a false assumption) on large
>> numbers, making IVs 64 bit doesn't change that.
>
> ??? Are you sure you know what you are talking about?

Sorry, I misread the ">=" as ">".

But from what I see, ($x + 0.5 >= $x) actually seems to be true for all
numbers, because the comparison is done on the NVs.

That, however, does lead to a result which may surprise the unwary:

#!/usr/bin/perl
use warnings;
use strict;
no warnings 'portable';

use Devel::Peek;

my $x1 = 18014398509481728.000000; # exact FP value
my $x2 = 18014398509481729; # exact 64 bit int value
if ($x1 >= $x2) {
print "surprise!\n";
}

hp