Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of Float overflow in C

Tags:

c

I am new to C, up until now I've only used OOP languages and never had to focus much on memory or how bits work, and I need help wrapping my head around what's happening here.

I have to test the minimum and maximum bounds of each data type in C by initializing a variable to the min/max value of the data type and attempting to add or subtract 1. I've gotten past the integer types and now I am confused on the behavior of the Float type. A lot of what I've been reading is a little over my head, I would really appreciate if someone could help me understand how these types work.

This is what I have for testing a Float:

void DisplayFloatMinimumAndMaximum()
{
// Declare variables
float fltMinimum = 0;
float fltMaximum = 0;

// Set min/max values
fltMinimum = -3.4e38;
fltMaximum = 3.4e38;

printf("Float Minimum and Maximum\n");
printf("------------------------------------------------\n");
printf("Float Minimum : %.10e\n", fltMinimum);
printf("Float Maximum : %.10e\n", fltMaximum);
printf("\n");

fltMinimum -= 1.0f;
fltMaximum += 1.0f;

printf("Confirmation\n");
printf("Float Minimum : %.10e\n", fltMinimum);
printf("Float Maximum : %.10e\n", fltMaximum);
printf("\n");
}

and I am getting a result of:

Float Minimum and Maximum
------------------------------------------------
Float Minimum : -3.3999999521e+38
Float Maximum : 3.3999999521e+38

Confirmation
Float Minimum : -3.3999999521e+38
Float Maximum : 3.3999999521e+38

It appears as nothing happened at all.
Is this the correct behavior? If so, why? If not, why?

(I am using Visual Studio 2015)

like image 336
user3691838 Avatar asked May 15 '17 20:05

user3691838


People also ask

What happens when a float overflows?

In general, a floating point overflow occurs whenever the value being assigned to a variable is larger than the maximum possible value for that variable. Floating point overflows in MODFLOW can be a symptom of a problem with the model.

What happens when overflow occurs in C?

Overview. Integer Overflow is a phenomenon that occurs when the integer data type cannot hold the actual value of a variable. Integer Overflow and Integer Underflow in C, do not raise any errors, but the program continues to execute (with the incorrect values) as if nothing has happened.

How does float work in C?

Float is a datatype which is used to represent the floating point numbers. It is a 32-bit IEEE 754 single precision floating point number ( 1-bit for the sign, 8-bit for exponent, 23*-bit for the value. It has 6 decimal digits of precision.

What is float () used for?

Float() is a method that returns a floating-point number for a provided number or string. Float() returns the value based on the argument or parameter value that is being passed to it. If no value or blank parameter is passed, it will return the values 0.0 as the floating-point output.


2 Answers

Due to the floating point nature of the data, adding/subbing 1 to such a big number does nothing because the value is "absorbed" (as Weather commented, before adding the two operands, they must be normalised so that both mantissae are expressed to the same power of 2. In doing so, if the smaller operand rolls down to 0 all of its significance is lost)

The value just stays the same, and you cannot reach the overflow/underflow.

http://www.fact-index.com/f/fl/floating_point_1.html

The minimum value to add to change the number is determined by the machine epsilon

The best way to toy with the limit is not to add but to multiply by (1+FLT_EPSILON) (amounts to add the number times FLT_EPSILON)

#include <float.h>
#include <stdio.h>

int main()
{
 float f = FLT_MAX;

 f *= (1+FLT_EPSILON/2);
 printf("%f\n",f);

return 0;
}

this prints the number, unchanged. Absorption ignored the multiplication.

Now do that:

#include <float.h>
#include <stdio.h>

int main()
{
 float f = FLT_MAX;

 f *= (1+FLT_EPSILON);
 printf("%f\n",f);

return 0;
}

and the output is

1.#INF00

In the case of FLT_MAX, on my machine, the limit number to add to trigger the overflow is way past 1: it is 40564816789451702000000000000000.000000 !

like image 160
Jean-François Fabre Avatar answered Oct 24 '22 19:10

Jean-François Fabre


Floating point limits

There are macros that define the limits. FLT_MAX, FLT_MIN are respectively the maximum and minimum values for the float type.

There are also other macros as well, such as FLT_MAX_EXP (maximum exponent defined in terms of FLT_RADIX which is generally valued at 2) and FLT_MAX_10_EXP (maximum exponent defined in base 10).

The smallest number representable in float is the floating point epsilon, defined in the FLT_EPSILON macro, valued at 1E-5.

These macros can be found in float.h

Precision

Note: In this explanation I will use a radix of 10 for the purposes of illustration. However C uses a radix defined by the FLT_RADIX macro mentioned above (usually valued at 2).

Floating point numbers are represented through a significand and an exponent:

1234 = 1.234 x 10^3

In C, single precision floating point numbers will give you 24 bits of significand, and 8 bits for the exponent. That means that if your significand has more digits than what can be encoded in the significant bits, it starts losing precision.

A very large number would be presented with a significand and an exponent.

1000000000000001 would become 1.000000000000001 x 10^15

This significand will be rounded as it is too large to be encoded in the significand bits. Likewise, adding small quantities to this number will also cause the significand to be rounded, therefore producing no increment.

like image 44
arboreal84 Avatar answered Oct 24 '22 17:10

arboreal84