Variable assignment and truncation of floats on x86

Joe Murray jmurray@dsrnet.com
Wed Apr 18 12:24:00 GMT 2001


All,

We had an extensive discussion with a number of different groups on this
problem but never found a good solution. We have tested this on Win98 w/ a
Borland Compiler, on several versions of Linux with several versions of GCC,
and on several RISC based workstations with GCC and other compilers.

This routine works as anticipated on all RISC machines regardless of the
compiler but fails on all x86 based machines (that we have) with GCC. If we
declare the variables volatile it works. My problem is that I have 600000
lines of code and I can't declare variables volatile everywhere or find all
of the potential locations of this problem.

A routine that demonstrates the problem is below. I can provide several
other examples. It was suggested previously that the floating point unit was
being put into truncate mode from its default round-to mode. I don't know
how to overcome this without major ramifications on the code baseline.

A summary of the routine is:

1. Assign some values to some integer variables.
2. Assign a floating point value from the division of two cast integers.
3. Assign a floating point value from the multiplication of two floats.
4. Assign an integer from a cast of a floating point product.
5. Assign an integer from a cast of a floating point number.

Result:

This is equiv to num = .35 * 20

3 results in: 7.0000000000 (actually probably 6.999999? rounded to
7.00000000)
4 results in: 6 <------- PROBLEM WITH INPLACE ASSIGNMENT
5 results in: 7 (correct answer)

Example routine:
-------------------------------------------------------
#include <stdio.h>

int main(void) {

  /* Assign some values to ints */
  int iaa = 28;
  int ibb = 80;
  int icc = 20;

  int imm, immO;
  float fll;
  float ftmp;

  fll = (float)iaa / (float)ibb;

  imm = ftmp = fll * (float)icc;

  printf("Direct assign float to float = %.10f\n", ftmp);
  printf(" Inplace assign float to int = %d\n", imm);

  immO = ftmp;
  printf("  Direct assign float to int = %d\n", immO);

  return(0);
}
-------------------------------------------------------

We can not find all of the instances of this problem and often it is
undetectable in many of the normalization processes of our systems. However,
the results are wrong and lead to the wrong solution.

Any help would be appreciated,

Joe



More information about the Gcc-bugs mailing list