If I have the following declaration:
float a = 3.0 ;
is that an error? I read in a book that 3.0
is a double
value and that I have to specify it as float a = 3.0f
. Is it so?
2.0 is a double literal value. 2.0f is a float literal value. 2 is an int literal value.
And the reason the comparison succeeds with 1.5 is that 1.5 can be represented exactly as a float and as a double ; it has a bunch of zeros in its low bits, so when the promotion adds zeros the result is the same as the double representation.
This is the most commonly used data type in programming languages for assigning values having a real or decimal based number within, such as 3.14 for pi. It has single precision. It has the double precision or you can say two times more precision than float.
In c a value of 1 is an integer and 1.0 is a double, you use f after a decimal number to indicate that the compiler should treat it as a single precision floating point number.
It is not an error to declare float a = 3.0
: if you do, the compiler will convert the double literal 3.0 to a float for you.
However, you should use the float literals notation in specific scenarios.
For performance reasons:
Specifically, consider:
float foo(float x) { return x * 0.42; }
Here the compiler will emit a conversion (that you will pay at runtime) for each returned value. To avoid it you should declare:
float foo(float x) { return x * 0.42f; } // OK, no conversion required
To avoid bugs when comparing results:
e.g. the following comparison fails :
float x = 4.2; if (x == 4.2) std::cout << "oops"; // Not executed!
We can fix it with the float literal notation :
if (x == 4.2f) std::cout << "ok !"; // Executed!
(Note: of course, this is not how you should compare float or double numbers for equality in general)
To call the correct overloaded function (for the same reason):
Example:
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } int main() { foo(42.0); // calls double overload foo(42.0f); // calls float overload return 0; }
As noted by Cyber, in a type deduction context, it is necessary to help the compiler deduce a float
:
In case of auto
:
auto d = 3; // int auto e = 3.0; // double auto f = 3.0f; // float
And similarly, in case of template type deduction :
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } template<typename T> void bar(T t) { foo(t); } int main() { bar(42.0); // Deduce double bar(42.0f); // Deduce float return 0; }
Live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With