|
Posted by Tim Roberts on 03/07/06 07:53
Oli Filth <catch@olifilth.co.uk> wrote:
>
>Anyway, I don't think the PHP behaviour Tim describes is consistent.
>For instance, try this in PHP:
>
> $a = 5543039444;
> $b = $a * 10000000000;
>
> echo $a . " => " . intval($a) . "\n";
> echo $b . " => " . intval($b) . "\n";
>
>PHP is clearly not just converting the floats to fully-represented
>integers and retaining only the 32 LSBs.
Actually, you're seeing an artifact of the design of the x86 FPU here. With
any fewer zeros, your code will print a number.
I looked up the PHP code; it is doing a simple C cast to unsigned long, and
writing the equivalent C program gets the same result:
int main(void)
{
double a = 5543039444;
double b = a * 10000000000;
printf( "%f %d\n", b, (unsigned long)b);
return 0;
}
C:\tmp>x
55430394439999996000.000000 0
C:\tmp>
The reason is that the mantissa in your example requires more than 64 bits,
which means it can no longer be represented exactly in an 80-bit FPU
register. In that case, the "fist" instruction raises an exception and
returns the "most negative integer". For an unsigned long, that is 0.
--
- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Navigation:
[Reply to this message]
|