2

I have to use bit/integer ops to figure out the epsilon for a given value in C. I know in terms of bit patterns that computing the next neighbor involves incrementing the mantissa, and if that overflows, to increment the exponent - but I'm not sure where to begin in terms of calculating the epsilon.

I can't use floating point math - so I need to generate the bit pattern directly. This makes it trickier because I cannot subtract.

Here's my understanding (based on some research I've done here on SO): the range changes obviously as the numbers get bigger, but I'm not sure how to use FLT_EPSILON to generate the right numbers. For 2^2x numbers, perhaps it is (FLT_EPSILON - 1) * number?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631

2 Answers2

4

If your epsilon is simply the value of one LSB increment to the mantissa, the value should be 2^(exp-23). So if your input is [s][exp][mantissa] your epsilon should be [0][exp-23][0]. Sure enough, when given an input of 1.0 ([0][127][0]), the result is [0][104][0] = 2^-23 = FLT_EPSILON.

MooseBoys
  • 6,641
  • 1
  • 19
  • 43
  • You beat me to it. Have a +1. – Quentin Jul 23 '14 at 16:16
  • It's one LSB increment to the mantissa, and in cases of overflow, and increment to the exponent as well. Does this property still hold? –  Jul 23 '14 at 16:17
  • @marchon It's a bit tricky at the overflow boundary, but that's because the definition of the epsilon kind of breaks down there, too. Depending on the formal definition you're going with, it may need to be tweaked. As an example, 1.0 is 2^-23 away from 1.0+eps, but it is only 2^-24 away from 1.0-eps. In that case, which is the right answer? The algorithm above will give the larger of the two, but you could easily add a check in that would give you the smaller value. – MooseBoys Jul 23 '14 at 16:20
  • Probably best to calculate both and go with the smaller. Thanks! –  Jul 23 '14 at 16:21
  • Sorry, have worked on it for a while - and I can't see what the check would be to return the smaller of the two. I can increase the exponent: if (mantissa + 1 >= (1 << 23)) exponent++; but how would I do this check and adjust accordingly? –  Jul 23 '14 at 17:40
2

due to IEEE 754 format you need 1 in mantissa and 127 shifted to 23

float x;

*((int*) &x) = 1;
*((int*) &x) = *((int*) &x) | 104 << 23;

printf("%.12f\n", FLT_EPSILON);
printf("%.12f\n", x);
Ivan Ivanov
  • 2,076
  • 16
  • 33