What is float, double, long double ?
To store numbers in a computer, an algorithm must be used. The C standard does not specify the algorithm, or the encoding to be used , for storing any kind of numbers, be it rational such as 1/2 , integer such as 5 or irrational such as pi .
It only specifies the name of the numerical data types, such as int , or float . Their meaning, for example int is used to store signed integer types , like -1 or 1 , and float is used to store approximation of real numbers such as 1.2 or -12.5 . Their minimum range, for example the minimum range of the int type is between -32767 and +32767 . The algorithms to encode numbers are specified by computer manufacturer.
The real types in C are the float , double , and long double . The C standard defines the model of real numbers that must be encoded , this model is called the floating point model , and it has the following format :
Multiple algorithms exist for encoding floating points , the most commonly used one is the IEEE floating point format .
On computers , that uses the IEEE floating point format algorithm , the float type maps to the IEEE single precision floating point , and the double type maps to the IEEE double precision floating point. The long double maps either to the IEEE quadruple precision floating point format, or the IEEE 80 bit floating point format.
The ranges of the C real types, when using the IEEE floating point format is as follow.
The float.h header , contain information related to floating point implementations, such as the absolute value of the range [min, max] for each of the floating types , and the closest value to 0 .
The type in which floating point arithmetic operations are performed , is defined in the macro FLT_EVAL_METHOD , defined in the header float.h .
If FLT_EVAL_METHOD value is set to 2 , then arithmetic operations are performed by promoting the operands to the long double type . If FLT_EVAL_METHOD is set to 1 , then arithmetic operations are performed by promoting the operands to long double , if any operand is of the long double type , otherwise operands are promoted to the double type , even if both operands are of the float type . If FLT_EVAL_METHOD is set to 0 , then arithmetic operations are done in the type of the widest operand. If FLT_EVAL_METHOD is set to -1 , then it is indeterminable.
Floating point literal
A floating point literal in C , can be written in decimal , in one of the following format :
where d is any digit between 0-9 , + means one or more, * means zero or more , what is between [] is optional , and e is case insensitive, and means an exponent of the number 10. As an example :
By default the type of a floating point literal in C, is the double type , unless suffixed with f , case insensitive, in this case it will be of the float type, or suffixed with l , case insensitive, in this case it will be of the long double type. As an example :
A floating point literal, can also be written in hexadecimal notation
Where 0x is case insensitive , and stands for hexadecimal, h is an hexadecimal digit between 0-F , + means one or more, what is between [] is optional, * means zero or more, and P is case insensitive , and means 2 to the power p , and d is one or more digits between 0-9 . As an example :
As with decimal floating point constant , hexadecimal floating point constant has a default type of double . To provide the hexadecimal floating point constant , a type of float , use the suffix f , case insensitive, and to give it the type of long double , use the suffix l , case insensitive. As an example :
Double VS Float in C++ – The Difference Between Floats and Doubles

Ihechikara Vincent Abba

In C++, there are various data types like string , int , char , bool , float , and double . Each of these data types have specific values that can be stored in them.
When working with integers, we usually store them in an int data type. But this is only useful for whole numbers.
When we want to store numbers with decimals, we can either use the float or double . Though these two data types are used for a similar purpose, they have some differences.
In this article, we’ll talk about the differences between floats and doubles in C++ along with some examples.
Difference Between Floats and Doubles
This section will be divided into sub-sections with each section focusing on one difference between floats and doubles.
Difference in Byte Size
The byte size for float is 4 while the byte size for double is 8.
This implies that double can store values that are twice the amount that float can hold.
We can see this by using the sizeof() operator. Here is an example:
Difference in Precision (Accuracy)
When working with numbers that have a lot of decimal digits, we usually hope that the resulting value will be accurate. But the accuracy of our result is dependent on the number of decimal digits we are dealing with.
Don’t worry, we’re still talking about C++, not mathematics.
float and double both have varying capacities when it comes to the number of decimal digits they can hold. float can hold up to 7 decimal digits accurately while double can hold up to 15.
Let’s see some examples to demonstrate this.
In the example above, we created float and double variables – both having the same value: 5.12345678987 .
The setprecision() function is used to tell the compiler the number of decimal places we want printed out. In our case, the value is 7.
We can observe from the results in the code above, that both variables printed accurate values up to the 7th decimal place: 5.123457 .
Let’s increase the parameter in the setprecision() function to 12 and see what happens.
From the results above, the MY_DOUBLE_VALUE variable printed out accurate values. But the MY_FLOAT_VALUE variable, from its 7th decimal place, printed out values entirely different from the original value it was given.
This shows us the precision of both data types. Just like float , if we try to return a value that exceeds the accuracy range for the double data type, we will get an inaccurate value returned.
Difference in Usage
float is mostly used in graphic libraries for high processing power due to its small range.
double is mostly used for calculations in programming to eliminate errors when decimal values are being rounded off. Although float can still be used, it should only be in cases when we’re dealing with small decimal values. To be on the safe side, you should always use double .
Conclusion
In this article, we talked about the differences between floats and doubles in C++.
We talked about three differences: byte size, precision, and usage.
We also learned that doubles have twice the byte size of floats. Also, doubles are more accurate when dealing with large decimal values.
Lastly, we talked about use cases which helped us understand when to use each data type.
What is the difference between float and double?
I’ve read about the difference between double precision and single precision. However, in most cases, float and double seem to be interchangeable, i.e. using one or the other does not seem to affect the results. Is this really the case? When are floats and doubles interchangeable? What are the differences between them?
![]()
14 Answers 14
As the name implies, a double has 2x the precision of float [1] . In general a double has 15 decimal digits of precision, while float has 7.
Here’s how the number of digits are calculated:
double has 52 mantissa bits + 1 hidden bit: log(2 53 )÷log(10) = 15.95 digits
float has 23 mantissa bits + 1 hidden bit: log(2 24 )÷log(10) = 7.22 digits
This precision loss could lead to greater truncation errors being accumulated when repeated calculations are done, e.g.
Also, the maximum value of float is about 3e38 , but double is about 1.7e308 , so using float can hit "infinity" (i.e. a special floating-point number) much more easily than double for something simple, e.g. computing the factorial of 60.
During testing, maybe a few test cases contain these huge numbers, which may cause your programs to fail if you use floats.
Of course, sometimes, even double isn’t accurate enough, hence we sometimes have long double [1] (the above example gives 9.000000000000000066 on Mac), but all floating point types suffer from round-off errors, so if precision is very important (e.g. money processing) you should use int or a fraction class.
Furthermore, don’t use += to sum lots of floating point numbers, as the errors accumulate quickly. If you’re using Python, use fsum . Otherwise, try to implement the Kahan summation algorithm.
[1]: The C and C++ standards do not specify the representation of float , double and long double . It is possible that all three are implemented as IEEE double-precision. Nevertheless, for most architectures (gcc, MSVC; x86, x64, ARM) float is indeed a IEEE single-precision floating point number (binary32), and double is a IEEE double-precision floating point number (binary64).
Here is what the standard C99 (ISO-IEC 9899 6.2.5 §10) or C++2003 (ISO-IEC 14882-2003 3.1.9 §8) standards say:
There are three floating point types: float , double , and long double . The type double provides at least as much precision as float , and the type long double provides at least as much precision as double . The set of values of the type float is a subset of the set of values of the type double ; the set of values of the type double is a subset of the set of values of the type long double .
The C++ standard adds:
The value representation of floating-point types is implementation-defined.
I would suggest having a look at the excellent What Every Computer Scientist Should Know About Floating-Point Arithmetic that covers the IEEE floating-point standard in depth. You’ll learn about the representation details and you’ll realize there is a tradeoff between magnitude and precision. The precision of the floating point representation increases as the magnitude decreases, hence floating point numbers between -1 and 1 are those with the most precision.
Given a quadratic equation: x 2 − 4.0000000 x + 3.9999999 = 0, the exact roots to 10 significant digits are, r1 = 2.000316228 and r2 = 1.999683772.
Using float and double , we can write a test program:
Running the program gives me:
Note that the numbers aren’t large, but still you get cancellation effects using float .
(In fact, the above is not the best way of solving quadratic equations using either single- or double-precision floating-point numbers, but the answer remains unchanged even if one uses a more stable method.)
- A double is 64 and single precision (float) is 32 bits.
- The double has a bigger mantissa (the integer bits of the real number).
- Any inaccuracies will be smaller in the double.
I just ran into a error that took me forever to figure out and potentially can give you a good example of float precision.
As you can see after 0.83, the precision runs down significantly.
However, if I set up t as double, such an issue won’t happen.
It took me five hours to realize this minor error, which ruined my program.
![]()
There are three floating point types:
- float
- double
- long double
A simple Venn diagram will explain about: The set of values of the types

![]()
The size of the numbers involved in the float-point calculations is not the most relevant thing. It’s the calculation that is being performed that is relevant.
In essence, if you’re performing a calculation and the result is an irrational number or recurring decimal, then there will be rounding errors when that number is squashed into the finite size data structure you’re using. Since double is twice the size of float then the rounding error will be a lot smaller.
The tests may specifically use numbers which would cause this kind of error and therefore tested that you’d used the appropriate type in your code.
Type float, 32 bits long, has a precision of 7 digits. While it may store values with very large or very small range (+/- 3.4 * 10^38 or * 10^-38), it has only 7 significant digits.
Type double, 64 bits long, has a bigger range (*10^+/-308) and 15 digits precision.
Type long double is nominally 80 bits, though a given compiler/OS pairing may store it as 12-16 bytes for alignment purposes. The long double has an exponent that just ridiculously huge and should have 19 digits precision. Microsoft, in their infinite wisdom, limits long double to 8 bytes, the same as plain double.
Generally speaking, just use type double when you need a floating point value/variable. Literal floating point values used in expressions will be treated as doubles by default, and most of the math functions that return floating point values return doubles. You’ll save yourself many headaches and typecastings if you just use double.
![]()
![]()
Floats have less precision than doubles. Although you already know, read What WE Should Know About Floating-Point Arithmetic for better understanding.
When using floating point numbers you cannot trust that your local tests will be exactly the same as the tests that are done on the server side. The environment and the compiler are probably different on you local system and where the final tests are run. I have seen this problem many times before in some TopCoder competitions especially if you try to compare two floating point numbers.
The built-in comparison operations differ as in when you compare 2 numbers with floating point, the difference in data type (i.e. float or double) may result in different outcomes.
If one works with embedded processing, eventually the underlying hardware (e.g. FPGA or some specific processor / microcontroller model) will have float implemented optimally in hardware whereas double will use software routines. So if the precision of a float is enough to handle the needs, the program will execute some times faster with float then double. As noted on other answers, beware of accumulation errors.
Quantitatively, as other answers have pointed out, the difference is that type double has about twice the precision, and three times the range, as type float (depending on how you count).
But perhaps even more important is the qualitative difference. Type float has good precision, which will often be good enough for whatever you’re doing. Type double , on the other hand, has excellent precision, which will almost always be good enough for whatever you’re doing.
The upshot, which is not nearly as well known as it should be, is that you should almost always use type double . Unless you have some particularly special need, you should almost never use type float .
As everyone knows, "roundoff error" is often a problem when you’re doing floating-point work. Roundoff error can be subtle, and difficult to track down, and difficult to fix. Most programmers don’t have the time or expertise to track down and fix numerical errors in floating-point algorithms — because unfortunately, the details end up being different for every different algorithm. But type double has enough precision such that, much of the time, you don’t have to worry. You’ll get good results anyway. With type float , on the other hand, alarming-looking issues with roundoff crop up all the time.
And the thing that’s not necessarily different between type float and double is execution speed. On most of today’s general-purpose processors, arithmetic operations on type float and double take more or less exactly the same amount of time. Everything’s done in parallel, so you don’t pay a speed penalty for the greater range and precision of type double . That’s why it’s safe to make the recommendation that you should almost never use type float : Using double shouldn’t cost you anything in speed, and it shouldn’t cost you much in space, and it will almost definitely pay off handsomely in freedom from precision and roundoff error woes.
(With that said, though, one of the "special needs" where you may need type float is when you’re doing embedded work on a microcontroller, or writing code that’s optimized for a GPU. On those processors, type double can be significantly slower, or practically nonexistent, so in those cases programmers do typically choose type float for speed, and maybe pay for it in precision.)
Name already in use
docs / docs / csharp / language-reference / builtin-types / floating-point-numeric-types.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Floating-point numeric types (C# reference)
The floating-point numeric types represent real numbers. All floating-point numeric types are value types. They are also simple types and can be initialized with literals. All floating-point numeric types support arithmetic, comparison, and equality operators.
Characteristics of the floating-point types
C# supports the following predefined floating-point types:
In the preceding table, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. They are interchangeable. For example, the following declarations declare variables of the same type:
The default value of each floating-point type is zero, 0 . Each of the floating-point types has the MinValue and MaxValue constants that provide the minimum and maximum finite value of that type. The float and double types also provide constants that represent not-a-number and infinity values. For example, the double type provides the following constants: xref:System.Double.NaN?displayProperty=nameWithType, xref:System.Double.NegativeInfinity?displayProperty=nameWithType, and xref:System.Double.PositiveInfinity?displayProperty=nameWithType.
The decimal type is appropriate when the required degree of precision is determined by the number of digits to the right of the decimal point. Such numbers are commonly used in financial applications, for currency amounts (for example, $1.00), interest rates (for example, 2.625%), and so forth. Even numbers that are precise to only one decimal digit are handled more accurately by the decimal type: 0.1, for example, can be exactly represented by a decimal instance, while there’s no double or float instance that exactly represents 0.1. Because of this difference in numeric types, unexpected rounding errors can occur in arithmetic calculations when you use double or float for decimal data. You can use double instead of decimal when optimizing performance is more important than ensuring accuracy. However, any difference in performance would go unnoticed by all but the most calculation-intensive applications. Another possible reason to avoid decimal is to minimize storage requirements. For example, ML.NET uses float because the difference between 4 bytes and 16 bytes adds up for very large data sets. For more information, see xref:System.Decimal?displayProperty=nameWithType.
You can mix integral types and the float and double types in an expression. In this case, integral types are implicitly converted to one of the floating-point types and, if necessary, the float type is implicitly converted to double . The expression is evaluated as follows:
- If there is double type in the expression, the expression evaluates to double , or to bool in relational and equality comparisons.
- If there is no double type in the expression, the expression evaluates to float , or to bool in relational and equality comparisons.
You can also mix integral types and the decimal type in an expression. In this case, integral types are implicitly converted to the decimal type and the expression evaluates to decimal , or to bool in relational and equality comparisons.
You cannot mix the decimal type with the float and double types in an expression. In this case, if you want to perform arithmetic, comparison, or equality operations, you must explicitly convert the operands either from or to the decimal type, as the following example shows:
You can use either standard numeric format strings or custom numeric format strings to format a floating-point value.
The type of a real literal is determined by its suffix as follows:
- The literal without suffix or with the d or D suffix is of type double
- The literal with the f or F suffix is of type float
- The literal with the m or M suffix is of type decimal
The following code demonstrates an example of each:
The preceding example also shows the use of _ as a digit separator. You can use the digit separator with all kinds of numeric literals.
You can also use scientific notation, that is, specify an exponent part of a real literal, as the following example shows:
There is only one implicit conversion between floating-point numeric types: from float to double . However, you can convert any floating-point type to any other floating-point type with the explicit cast. For more information, see Built-in numeric conversions.
C# language specification
For more information, see the following sections of the C# language specification: