Someone asked this question yesterday. I understand that java interprets 3.0
to be a double
, and 3f
to be a float
, and the doubles
have 64-bit precision and floats
have 32-bit precision. If someone asked me, I would have given an answer similar to the ones given; however, I wanted to provide empirical evidence that made it very clear that java
stores 3.0
and 3f
differently.
Here's what I attempted, but to little avail:
System.out.println("Double: " + Double.toHexString(d)); //prints 0x1.8p1
System.out.println("Float: " + Float.toHexString(f)); //prints 0x1.8p1
System.out.println("Double: " + new Double(d).byteValue()); //prints 3
System.out.println("Float: " + new Float(f).byteValue()); //prints 3
Long l = Double.doubleToLongBits(d);
Integer i = Float.floatToIntBits(f);
System.out.println("Double (long bits): " + l); //prints 4613937818241073152
System.out.println("Float (int bits): " + i); //prints 1077936128
These are different, but that's because floats
use single-format (an 8-bit biased exponent), and doubles
use double-format (an 11-bit biased exponent). For more information, see IEEE Arithmetic. I converted both to their binary representations, but again didn't get anywhere:
System.out.println("Long-toBinary: " + Long.toBinaryString(l));
//prints 100000000001000000000000000000000000000000000000000000000000000
System.out.println("Integer-toBinary: " + Integer.toBinaryString(i));
//prints 1000000010000000000000000000000
While there are more 0's
in the Long.toBinaryString(l)
, multiplying by addition 0's
will not change the result (the differing position of the 1 in the beginning is due to the 8-bit vs 11-bit biased exponent issue). So, I still don't have empirical evidence as to why the multiplication from the question below yields two different answers.
97346822*3f, result is 2.9204048E8,
however
97346822*3.0 gives me 2.92040466E8.
3f
and 3.0
must be different for the results to be different, but I can not come up with anything showing that they actually are. Again, I understand that 3f
is interpreted as a float
and 3.0
as a double
, please do not respond with answers merely stating this.
EDIT:
To clarify, I am trying to isolate 3.0
and 3f
and show that they are indeed different.
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 answer your question, you can add a float to a double and vice versa. Generally, the result will be made into a double , and you will have to cast it back to a float if that is what you want.
Size: Float is of size 32 bits while double is of size 64 bits. Hence, double can handle much bigger fractional numbers than float. They differ in the allocation of bits for the representation of the number. Both float and double use 1 bit for representing the sign of the number.
This answer also deals with this one.
Their values are equal. We have some exponent and 2 consecutive ones in the value. This represents 3.0 and 3f equally. Now the problem is the floating-point multiplication. each floating point multiplication occurs on processor hardware, and all of the multiplication happens within a floating-point value itself, in the same precision(double/float). While the values 3.0
and 3f
are equal, they are not equal in regards to how a multiplication occurs with them. This does not matter with strictfp
on my system as my CPU matches the IEEE 754 standard precisely.
This code could clue you in:
BigDecimal val1=new BigDecimal(97346822*3f);
BigDecimal val2=new BigDecimal(97346822*3.0);
System.out.println(val1.subtract(val2, MathContext.UNLIMITED).toEngineeringString());
System.out.println(val1.equals(val2));
System.out.println(val1.compareTo(val2));
This creates two BigDecimals from our values.
First output is the difference as an engineering string, namely 14
, not 0
.
Second output is false
showing that BigDecimal does not find them to be of equal value and precision.
Third output gives 1
. Therefore value 1 is greater than value 2 in the context of BigDecimal.
Printing both precision(
results shows they both have a precision of 9.
Let's run the same code with different values:
BigDecimal val1=new BigDecimal(3.1f);
BigDecimal val2=new BigDecimal(3.1);
System.out.println(val1.subtract(val2, MathContext.UNLIMITED).toEngineeringString()); //-95.367431729442841970012523233890533447265625E-9
System.out.println(val1.equals(val2)); //false
System.out.println(val1.compareTo(val2)); // -1
System.out.println(val1.precision()); // 22
System.out.println(val2.precision()); // 52
We can see that the same literal decimal, in float/double value, represents provably distinct values. In this case, the decimal 3.1 cannot be fit cleanly into a binary decimal. A similar effect happens with base 10 decimals and the fraction 2/3. While 2/3 would be written as:
_
0.6
We'd write it with a limited length as 0.66666667. If we had a longer length, it would be something like 0.6666666666666667.
When taken literally, 0.66666667!=0.6666666666666667.
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