G'day,
Thanks for the added initialisation of hue, in response to a compiler
warning that the variable might be used before being initialised.
This initialisation was added as r739 to CD, to the file
cd/src/drv/cddxf.c, line 1662.
As I mentioned previously, I always break out in a sweat when
floating-point (nominally double-precision, in this case) entities
are subject to an equality check. This happens in the altered
function (RGB_to_HSB) in a number of places, especially in the
paragraph:
if (*sat != 0) /* hue from 0 to 359 */
{
if (red == maximum) *hue = (green - blue)/delta;
if (green == maximum) *hue = 2 + (blue - red)/delta;
if (blue == maximum) *hue = 4 + (red - green)/delta;
*hue *= 60;
if (*hue < 0) *hue += 360;
}
While digging around various places regarding floating-point
equality in general (I was focussing on the internal 80-bit
double-extended format versus the 64-bit double format), I found a
surprise, or, more precisely, a "disappointment" in the GCC
documentation (info gcc):
Section 13.6 Disappointments and Misunderstandings
==================================================
[...]
* On 68000 and x86 systems, for instance, you can get paradoxical
results if you test the precise values of floating point numbers.
For example, you can find that a floating point value which is not
a NaN is not equal to itself. This results from the fact that the
floating point registers hold a few more bits of precision than
fit in a `double' in memory. Compiled code moves values between
memory and floating point registers at its convenience, and moving
them into memory truncates them.
You can partially avoid this problem by using the `-ffloat-store'
option (*note Optimize Options::).
[...]
So, when dealing with optimized floating-point code, it's possible
to have code that seems absurd, such as (for "float x;" and/or
"double x;"; perhaps also other floating-point formats):
x = PARADOXICAL_VALUE;
if (x == x)
printf("%s\n", "equal");
else
printf("%s\n", "not equal?!");
and the output would be "not equal?!\n". (This is a very, very,
slimmed-down example; where optimization is enabled, the compiler
might be able to trace code flow here, although I don't know if
the presence of floating-point almost immediately cuts off some
analysis opportunities.)
-----
For the function in question, the colour parameters are:
unsigned char r, unsigned char g, unsigned char b
and are immediately converted to the double variables:
double red = r / 255.0;
double green = g / 255.0;
double blue = b / 255.0;
If r/g/b were converted to signed-integer variables (at least
16-bit), then some of the contentious equality-test cases could
operate on the integer variables, bypassing the floating-point
uncertainty.
The function could be reworked so that the majority of operations
use signed integer variables derived from the r/g/b parameters,
and defer double-precision conversions until as late as possible.
cheers,
sur-behoffski
programmer, Grouse Software
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Iup-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/iup-users