Skip to content

Instantly share code, notes, and snippets.

@encryptio
Created November 2, 2015 20:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save encryptio/fe12b7ac8907ecb5369d to your computer and use it in GitHub Desktop.
Save encryptio/fe12b7ac8907ecb5369d to your computer and use it in GitHub Desktop.
Floating point weirdness
// Compile and run in 32-bit mode:
// $ cc -Wall -m32 -o test test.c
// $ ./test
// false
//
// Contrast with 64-bit mode:
// $ cc -Wall -m64 -o test test.c
// $ ./test
// true
//
// This happens because the default implementation of floating point math on
// 32-bit x86 is to use the 387 floating point instruction set, which has higher
// internal precision. Thus, "div" is flushed to RAM (and truncated to low
// precision), then the comparison loads it back into the 387 unit and does the
// division again (but does not truncate it before comparison, since it's not
// stored in a variable (memory.))
//
// By contrast, 64-bit x86 uses the SSE instructions for floating point math,
// which has instructions for operations on 32-bit floats directly. Thus, its
// internal representation is already truncated to the proper size, and the
// equality check succeeds.
//
// You can compile and run in 32-bit mode with SSE (instead of 387):
// $ cc -Wall -m32 -mfpmath=sse -o test test.c
// $ ./test
// true
//
// You might need to set -msse or other options to get this to work; my "cc" is
// gcc 5.2.0.
#include <stdio.h>
int main(void) {
float three = 3.0f;
float seven = 7.0f;
float div = three/seven;
if (div == three/seven)
printf("true\n");
else
printf("false\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment