On 09/08/2014 10:30 PM, Frank Ch. Eigler wrote:
Mark Goodwin <mgoodwin@xxxxxxxxxx> writes:
[...]
I checked the raw values:
the correct value is 0.05 = (7504 - 7503) / 20.00 [...]
Here's pmval on RHEL65/i386 (32bit) :
Breakpoint 2, printreal (v=0.049999999799474608, minwidth=21) at pmval.c:456
Breakpoint 1, printreal (v=0.050000000000000003, minwidth=21) at pmval.c:456
Both are wrong! - as checked above, the correct value is 0.05. [...]
Not sure about that - binary floating point calculations naturally
vary between compiler versions / cpu families / optimization levels,
and those two numbers are identical to apprx. ~28 bits of mantissa.
The test should have a larger epsilon range for acceptance.
The time delta calculations are all supposed to be done in double
precision arithmetic, so I'd agree if the mantissa are within ~60 bits ...
Anyway, I've narrowed down the error to the time delta calculation
in __pmtimevalToReal() where the tv_nsec conversion to seconds
part of the calculation appears to be done with single precision
floating point before being cast to double. The following one
character patch in libpcp promotes it to double precision, and seems
to fix the issue (though I'm out of time tonight to be completely
sure this is the root cause!)
diff --git a/src/libpcp/src/tv.c b/src/libpcp/src/tv.c
index cabdf75..8d2baf8 100644
--- a/src/libpcp/src/tv.c
+++ b/src/libpcp/src/tv.c
@@ -41,7 +41,7 @@ double
__pmtimevalToReal(const struct timeval *val)
{
double dbl = (double)(val->tv_sec);
- dbl += (double)val->tv_usec / 1000000.0;
+ dbl += (double)val->tv_usec / 1000000.0L;
return dbl;
}
|