Watcom 10.6 compiler "feature"

Background.
Binary data generated on big-endian machine.
read in on Intel platform, (QNX 4.25), and byte swapped

Problem occurs for some patterns of float.

code looks something like

float swab_f ( float f ) {
float ftmp;
/* Byte swab f into ftmp */
return( ftmp );
}

float ftmp;
ftmp = fread( &ftmp, 4, fp);
ftmp = swap_f( ftmp);

For ftmp 0x7f95a5bd read from file
f becomes 0x7fd5a5bd when examined in swab_f before any code executed.

value returned is -0.0809736 and -0.0808515 is expected.
Doesn’t seem like much, but generated a 42cm error in the height of terrain
calculation for the vehicle simulation we were executing, a big bump.

Problem goes away if the code is optimized, or if float * is passed
to swab_f instead of the value.

As read in value is NaN, bits 1-8 == ffff, but why does bit 9 get set when
pushing/popping? value on the stack, and why does issue go away when
optimized? It this behavior something I should have expected?

“John Dibbs” <johnd@faac.com> wrote in message
news:bjss6n$aib$1@tiger.openqnx.com

Background.
Binary data generated on big-endian machine.
read in on Intel platform, (QNX 4.25), and byte swapped

Problem occurs for some patterns of float.

code looks something like

float swab_f ( float f ) {
float ftmp;
/* Byte swab f into ftmp */
return( ftmp );
}

float ftmp;
ftmp = fread( &ftmp, 4, fp);
ftmp = swap_f( ftmp);


For ftmp 0x7f95a5bd read from file
f becomes 0x7fd5a5bd when examined in swab_f before any code executed.

value returned is -0.0809736 and -0.0808515 is expected.
Doesn’t seem like much, but generated a 42cm error in the height of
terrain
calculation for the vehicle simulation we were executing, a big bump.

Problem goes away if the code is optimized, or if float * is passed
to swab_f instead of the value.

As read in value is NaN, bits 1-8 == ffff, but why does bit 9 get set when
pushing/popping? value on the stack, and why does issue go away when
optimized? It this behavior something I should have expected?

Float are evil :wink:

My guess is difference in the way the float store, memory versus register,
which is probably why you see a difference between optimized and non
optimized. Of course using a pointer is much better.

I don’t think this is normal, as optimized and non optimized should yield
the same results, but you will have to live with it!



“John Dibbs” <johnd@faac.com> wrote in message
news:bjss6n$aib$1@tiger.openqnx.com

Background.
Binary data generated on big-endian machine.
read in on Intel platform, (QNX 4.25), and byte swapped

Problem occurs for some patterns of float.

code looks something like

float swab_f ( float f ) {
float ftmp;
/* Byte swab f into ftmp */
return( ftmp );
}

float ftmp;

The next line in your code caught my attention:

ftmp = fread( &ftmp, 4, fp);

You don’t really assign fread() return value to ftmp, do you?

ftmp = swap_f( ftmp);

For ftmp 0x7f95a5bd read from file
f becomes 0x7fd5a5bd when examined in swab_f before any code executed.

value returned is -0.0809736 and -0.0808515 is expected.
Doesn’t seem like much, but generated a 42cm error in the height of
terrain
calculation for the vehicle simulation we were executing, a big bump.

Problem goes away if the code is optimized, or if float * is passed
to swab_f instead of the value.

As read in value is NaN, bits 1-8 == ffff, but why does bit 9 get set when
pushing/popping? value on the stack, and why does issue go away when
optimized? It this behavior something I should have expected?

A.E.K. wrote:

ftmp = fread( &ftmp, 4, fp);

You don’t really assign fread() return value to ftmp, do you?

Correct, I was paraphrasing the code and got a little sloppy.
Code is actually.

if(fread( &ftmp, 1, 4, fp) != 4) {
syslog( LOG_ERR, “fread error”);
}
I was more interested in why bit 9 gets set when passing NaN to a function.

“John Dibbs” <> johnd@faac.com> > wrote in message
news:bjss6n$aib$> 1@tiger.openqnx.com> …
Background.
Binary data generated on big-endian machine.
read in on Intel platform, (QNX 4.25), and byte swapped

Problem occurs for some patterns of float.

code looks something like

float swab_f ( float f ) {
float ftmp;
/* Byte swab f into ftmp */
return( ftmp );
}

float ftmp;

The next line in your code caught my attention:

ftmp = fread( &ftmp, 4, fp);

You don’t really assign fread() return value to ftmp, do you?

ftmp = swap_f( ftmp);

For ftmp 0x7f95a5bd read from file
f becomes 0x7fd5a5bd when examined in swab_f before any code executed.

value returned is -0.0809736 and -0.0808515 is expected.
Doesn’t seem like much, but generated a 42cm error in the height of
terrain
calculation for the vehicle simulation we were executing, a big bump.

Problem goes away if the code is optimized, or if float * is passed
to swab_f instead of the value.

As read in value is NaN, bits 1-8 == ffff, but why does bit 9 get set when
pushing/popping? value on the stack, and why does issue go away when
optimized? It this behavior something I should have expected?

I was more interested in why bit 9 gets set when passing NaN to a
function.

I haven’t really researched the code gen difference, but I think you’re
making an assumption in your code that you shouldn’t be.

NaN is representable with the sign bit set to 0, the exponent to 11111111,
and the fractional component to ~=0. That means NaN can be represented in
many ways, and passing a NaN means you’ll get NaN from the parameter,
nothing more, and certainly nothing about how NaN is represented.

If you’re byte swapping a float, you should pass it in as either an uint32_t
or a pointer to that data (or a container you know is big enough to hold the
float), do the byte swapping operation on it, and then load it into a float.

-Adam