|
From: <HBB...@t-...> - 2007-04-09 21:05:23
|
Daniel J Sebald wrote:
> Note that this sampling contains both "integers" and "floats".
Let's try and use clear terminology. Those aren't integers, they're
floats with integer values. Yes, there is a difference.
> But this is not how the innards of the pow(), floor(), etc. functions work:
Again, careful of the wording. There are two floor() functions you
could be talking about: the gnuplot operator (standard.c:f_floor()), or
the C standard library function. They behave differently, because they
take arguments of different types. Our floor() takes actual integers or
complex floating-point arguments, the C standard function takes doubles.
> The documentation of these C functions might say "largest integer not greater
> than arg", but that means the math vernacular, not computer vernacular.
Which is why that's not what it says. What the only documentation we
can rely on, i.e. the C Standard, says about floor is (C99 7.12.9.2p2):
The floor functions compute the largest integer value not greater than x.
The key word is "integer value". This is not an integer, but a
floating-point number of integer value.
> Given gnuplot's behavior, can we come up with a comparison at the command line
> the reflects the behavior of C routines? I've followed the parsing to
> internal.c and see that ** operator does in fact use the C library pow(,)
> function.
It's not quite as simple as that. f_power uses pow() (and some
trigonometry) for floating-point arguments, but iterated multiplication
for integer**integer.
> Very strange. Not concrete proof, but my conjecture about not knowing which is
> more accurate, outright multiplying via dbl_raise() vs. pow(), does seem a
> pertinent question.
Not really, because utmost accuracy is at most half the picture here.
Trying to "make sure we get exactly the right result for xnorm" is a
futile effort, because we a) don't need it exactly right, and b) we
can't get it, anyway.
The real problems aren't with pow() vs. dbl_raise() --- pow() would just
fail in a different way on the [NaN:NaN] range example that re-triggered
this discussion. They're with the overall result of
quantize_{normal|duodecimal}_tics(), for inputs that don't quite lie on
the integer values the users think they see, because of rounding or
sampling inaccuracies that took place before scaling even began. E.g.
if the actual y range is [0:100+epsilon], how should the tic interval
and auto-extended range endpoint depend on the sign and magnitude of
epsilon, at small values?
And that's before we consider that we have exactly zero control over the
quality of a given C compiler's math library, and thus their pow()
function. dbl_raise() may not be the shiniest tool in the shed, but at
least it's _our_ tool. Its behaviour may vary a good deal less from one
platform to the next than that of pow().
|