E
Eric Wilhelm
I'm running into some problems where 1+1 != 2.
I've tried compiling 5.8.0 and 5.9.0 with -Duselongdouble and
XS::APItest::have_long_double() returns true, but I still cannot
get the following code to perform correctly:
# test floating-point accuracy
@a = (40.23445,10.7784); # this will fail
# @a = (0,0); # this will succeed
$r = 3/16;
$pi = atan2(1,1) * 4;
$ang = 12 * $pi / 180;
@s = ( $a[0] + $r * cos($ang), $a[1] + $r * sin($ang) );
@f = ( $a[0] - $r * cos($ang), $a[1] - $r * sin($ang) );
$dist = sqrt( ($f[0] - $s[0])**2 + ($f[1] - $s[1])**2);
$d = 2 * $r;
if($dist != $d) {
print "failed: $dist != $d\n";
}
else {
print "okay: $dist == $d\n";
}
# end
this gives:
failed: 0.374999999999999998 != 0.375
unless @a is set to (0,0)
Recreating the process in C and declaring everything as double gives the
same results, but if you declare as long double it will come up with
matching numbers, thus the quest to get a Perl working with long doubles.
Anyone have similar experiences? Any way to fix this? Rounding is not
a solution, because the contents of @s and @f are the desired product,
and the distance between them needs to be 2 * $r when computed with long
doubles (i.e. the inaccuracy apparently happens in the addition as
opposed to the distance calculation.)
Thanks,
Eric
I've tried compiling 5.8.0 and 5.9.0 with -Duselongdouble and
XS::APItest::have_long_double() returns true, but I still cannot
get the following code to perform correctly:
# test floating-point accuracy
@a = (40.23445,10.7784); # this will fail
# @a = (0,0); # this will succeed
$r = 3/16;
$pi = atan2(1,1) * 4;
$ang = 12 * $pi / 180;
@s = ( $a[0] + $r * cos($ang), $a[1] + $r * sin($ang) );
@f = ( $a[0] - $r * cos($ang), $a[1] - $r * sin($ang) );
$dist = sqrt( ($f[0] - $s[0])**2 + ($f[1] - $s[1])**2);
$d = 2 * $r;
if($dist != $d) {
print "failed: $dist != $d\n";
}
else {
print "okay: $dist == $d\n";
}
# end
this gives:
failed: 0.374999999999999998 != 0.375
unless @a is set to (0,0)
Recreating the process in C and declaring everything as double gives the
same results, but if you declare as long double it will come up with
matching numbers, thus the quest to get a Perl working with long doubles.
Anyone have similar experiences? Any way to fix this? Rounding is not
a solution, because the contents of @s and @f are the desired product,
and the distance between them needs to be 2 * $r when computed with long
doubles (i.e. the inaccuracy apparently happens in the addition as
opposed to the distance calculation.)
Thanks,
Eric