Reputation: 2432
This might be the simple question to all but it messes with my head with a question,"Why it is so?"
As you can see in the below code, I have declared a float
variable and assigned a value to it. When this piece of code get's compiled and interpreted, I will get an error as possible loss of precision
which is right as default data type of java interpreter for floating constant is double.
Query 1 : I wonder, why should I waste memory in my application for double when my floating constant can accommodate in number of bytes float provide.
Query 2: Now if I specify float a = 3.1415f ;
I will get the output but now how much memory is allocated for my a
variable.
float a = 3.1415 ;
System.out.println("Value of a:"+a);
I really want to understand this hack, why is it so?
Upvotes: 2
Views: 516
Reputation: 3417
let me answer with a question:
why does this small fragment of code print false and not true?
float a = 3.1415;
double b = 3.1415;
double c = a;
System.out.println((b==c));
... got it? exactly!
However it is true that this is not the whole logic, since 0.1f and 0.1 are different numbers in binary representation, but 0.5f and 0.5 are the same, the compiler should allow you to declare float f = 0.5; but it does not evaluate if each number "fits" in afloat or requires a double without precision loss... it just assumes precision will be lost for the vast majority, and is rightly so.
Upvotes: 0
Reputation: 1500495
Query 1 : I wonder, why should I waste memory in my application for double when my floating constant can accommodate in number of bytes float provide.
It's simply a matter of floating point literals defaulting to double
. From section 3.10.2 of the JLS:
A floating-point literal is of type float if it is suffixed with an ASCII letter F or f; otherwise its type is double and it can optionally be suffixed with an ASCII letter D or d (§4.2.3).
You need to decide which type you want, and write the appropriate literal. You almost certainly shouldn't base your choice of data type on how many digits you specify - and be aware that just because float
can maintain up to a certain number of decimal digits of accuracy doesn't mean that it can exactly represent numbers with that many significant digits. No binary floating point type can exactly represent 0.1 for example, in the same way that you can't write "one third" as a finite decimal number.
As a side note, personally I like to add the d
explicitly for double
anyway, just for clarity.
Next:
Query 2: Now if I specify float a = 3.1415f ; I will get the output but now how much memory is allocated for my a variable.
4 bytes, because it's a float
.
Upvotes: 2
Reputation: 26185
"Query 1 : I wonder, why should I waste memory in my application for double when my floating constant can accommodate in number of bytes float provide."
This incorporates a false assumption. Neither float nor double can really store your value:
float: 3.141499996185302734375
double: 3.141500000000000181188397618825547397136688232421875
Both are approximations, but the double is a much closer approximation than the float.
If you are not going to think about the required precision for a literal, it is safer to use double, so that it the appropriate default. If you have analyzed the effect of float rounding error, and have decided float is acceptable, you can and should make it a float literal.
Upvotes: 1
Reputation: 1382
As defined in the spec, a float is a 32-bit IEEE 754 value, so it consumes 4 bytes. This document explains the defaults and the reasoning: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html. Sun/Oracle's advice is that if the precision of a double is not needed, and memory is an issue, use a float as you have done.
Upvotes: 0
Reputation: 29166
Query 1: Because floating point calculations are almost always involve approximation. double
types has a larger precision (double-precision) that float, so it has a reduced chance of losing any data due to approximation. I think this may be a reason for considering any floating point literals as doubles.
Query 2: For both of the cases your a
variable will be 32-bit in size (check out the float section here). In the -
float a = 3.1414;
statement, the value is being cast into a float, which is known as a narrowing conversion. Java doesn't allow that, but it allows the opposite - widening conversion.
Upvotes: 0