This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/18275] New: Copying float that is nan to another variable twiddles bit


[Bug does not appear in 2.96/3.x and forward]

'gcc -v'
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/specs
gcc version 2.95.3 20010315 (release)

To duplicate bug, build the following (gcc -o test main.c)

The program attempts to take t, print it bit-by-bit, byte swap it, print that 
swapped value, then swap it back to its original value.  The swapped value 
becomes corrupt.  This bug shows up in 2.95 and prior, but 2.96/3.x and higher 
do not have this problem.

/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* some magic values that will demonstrate the bug. */
/* 
float t = 119.774410;
float t = 117.774410;
float t = 110.774410;
 */

void swap_float(float *word);
void print_char(char);
void print_bytes(void *, int);

int main(int argc, char** argv) {
  float t = 119.774410;

  printf("t = %f\n", t);
  print_bytes( (void *)&t, sizeof(t) );
  printf("\n");

  swap_float(&t);
  printf("swapped t = %f\n", t);
  print_bytes( (void *)&t, sizeof(t) );
  printf("\n");

  swap_float(&t);
  printf("unswapped t = %f\n", t);
  print_bytes( (void *)&t, sizeof(t) );
  printf("\n");

  return 0;
}

void print_char(char x) {
  int b;
  char test[256];

  for (b = 0; b < sizeof (x) * 8; b++) {
    if (x & 01) test[(sizeof(x) * 8) - b -1] = '1';
      else test[(sizeof(x) * 8) - b -1] = '0';
    x >>= 1;
  }
  test[sizeof(x) * 8] = '\0';
  printf("%s", test);
}

void print_bytes(void *startBytes, int numBytes) {
  int i = 0;
  char *curChar;

  curChar = startBytes;

  for (i = 0; i < numBytes; i++) {
    print_char( *curChar );
    printf(" | ");
    curChar++;
  }
}

void swap_float(float *word) {
  unsigned int temp[4];

  union {
    unsigned int    iword;
    float           fword;
  } eq;

  eq.fword = *word;

  temp[0] = eq.iword & 0x000000ff;
  temp[1] = (eq.iword & 0x0000ff00) >> 8;
  temp[2] = (eq.iword & 0x00ff0000) >> 16;
  temp[3] = (eq.iword & 0xff000000) >> 24;

  eq.iword = (temp[0] << 24) + (temp[1] << 16) + (temp[2] << 8) + temp[3];

  *word = eq.fword;
}
/* End main.c */

-- 
           Summary: Copying float that is nan to another variable twiddles
                    bit
           Product: gcc
           Version: 2.95.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P1
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dsracic at gmail dot com
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18275


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]