This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
When I tried the following codes in Java:
System.out.println("0.1d/0.3d is " + 0.1d/0.3d)
System.out.println("0.1f/0.3d is " + 0.1f/0.3d)
I get the following output:
0.1d/0.3d is 0.33333333333333337
0.1f/0.3d is 0.3333333383003871
If float/double should get a double then float/double should be same with double/double in this case.
Just execute the below code to see binary string of number you want to check for:
System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1d)));
System.out.println(Integer.toBinaryString(Float.floatToIntBits(0.1f)));
Output:
11111110111001100110011001100110011001100110011001100110011010
111101110011001100110011001101
And you see the difference in float bits and double bits. so we can't get the same result for float/double and double/double for a longer precision values .
yes "milbrandt" said right when we are converting float quantity into double by implicit typecasting some information at decimal point will differ. That's why it is showing the different result while dividing float/ double.
As you probably know, double uses 64 bits to store a value but float 32 bits.
To represent significand, double uses 52 bits, and float uses 23 bits. Thus double can give 15 digit precision at most, and float can give 7.
If you do float / double, you actually try to divide a floating point with 7 digit precision at most (far to exact) by a floating point with 15 digit precision at most (closer to exact), and then implicitly typecast the result to a floating point with 15 digit precision. The typecast cannot restore your result from 7 digit precision to 15 digit. Therefore, the results are different though both of them are double.
initialize a double with a float and divide then. You will see the same result.
double f = 0.1f;
double d = 0.1d;
double n = 0.3d;
System.out.println("float /double = " + f/n);
System.out.println("double/double = " + d/n);
result is
float /double = 0.3333333383003871
double/double = 0.33333333333333337
The reason why you see this difference is because you don't have these exact values.
Even if we suppose 0.1d and 0.3d would be exact (which they aren't, what you can see on the result 0.33333333333333337), 0.1f is 0.10000000149011612, which makes the difference.
Related
This question already has answers here:
How to round up the result of integer division?
(18 answers)
How to round up integer division and have int result in Java? [duplicate]
(9 answers)
Closed 4 years ago.
I know I can use Math.java functions to get the floor, ceil or round value for a double or float, but my question is -- Is it possible to always get the higher integer value if a decimal point comes in my value
For example
int chunkSize = 91 / 8 ;
which will be equal to 11.375
If I apply floor, ceil or round to this number it will return 11 I want 12.
Simply If I have 11.xxx I need to get 12 , if I have 50.xxx I want 51
Sorry The chunkSize should be int
How can I achieve this?
Math.ceil() will do the work.
But, your assumption that 91 / 8 is 11.375 is wrong.
In java, integer division returns the integer value of the division (11 in your case).
In order to get the float value, you need to cast (or add .0) to one of the arguments:
float chunkSize = 91 / 8.0 ;
Math.ceil(chunkSize); // will return 12!
ceil is supposed to do just that. I quote:
Returns the smallest (closest to negative infinity) double value that
is greater than or equal to the argument and is equal to a
mathematical integer.
EDIT: (thanks to Peter Lawrey): taking another look at your code you have another problem. You store the result of integer division in a float variable: float chunkSize = 91 / 8 ; java looks at the arguments of the division and as they are both integers it performs integer division thus the result is again an integer (the result of the division rounded down). Now even if you assign this to the float chunkSize it will still be an integer(missing the double part) and ceil, round and floor will all return the same value. To avoid that add a .0 to 91: float chunkSize = 91.0 / 8;. This makes one of the arguments double precision and thus double division will be performed, returning a double result.
If you want to do integer division rounding up you can do
x / y rounded up, assuming x and y are positive
long div = (x + y - 1) / y;
In your case
(91 + 8 - 1) / 8 = 98 / 8 = 12
This works because you want to round up (add one) for every value except an exact multiple (which is why you add y - 1)
Firstly, when you write float chunkSize = 91 / 8 ; it will print 11.0 instead of 11.375
because both 91 and 8 are int type values. For the result to be decimal value, either dividend or divisor
or both have to be decimal value type. So, float chunkSize = 91.0 / 8; will result 11.375 and
now you can apply Math.ceil() to get the upper value. Math.ceil(chunkSize); will result in 12.0
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 9 years ago.
I have a number of fields which take inputs, a process which happens and then fields that show the output. My issue is that for some reason math.round seems to be always rounding down instead of to the nearest integer.
Here is an example
private void method(){
int X= Integer.parseInt(XjTF.getText());
int Y= Integer.parseInt(YjTF.getText());
float Z =(X+Y)/6;
int output = Math.round(Z);
OutputjTF.setText(Integer.toString(output)+" =answer rounded to closest integer");
}
Your X and Y variables are int, so Java performs integer division, here when dividing by 6. That is what is dropping the decimal points. Then it's converted to a float before being assigned to Z. By the time it gets to Math.round, the decimal points are already gone.
Try casting X to float to force floating point division:
float Z =((float) X + Y)/6;
That will retain the decimal information that Math.round will use to properly round its input.
An alternative is to specify a float literal for 6, which will force the sum of X and Y to be cast to float before the division:
float Z = (X + Y)/6.0f;
It can't just be 6.0, because that's a double literal, and the Java compiler will complain about "possible loss of precision" when attempting to assign a double to a float.
Here's the relevant quote from the JLS, Section 15.17.2:
Integer division rounds toward 0. That is, the quotient produced for
operands n and d that are integers after binary numeric promotion
(§5.6.2) is an integer value q whose magnitude is as large as possible
while satisfying |d · q| ≤ |n|.
This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 9 years ago.
I have the following and the question is, for example if zzi = 95 then myNum will be correctly displayed as 32.33, exactly as I want it too with two decimal places.
However if zzi = 94, myNum will be displayed as 32.0 instead of 32.00
How to display it as 32.00?
float xFunction(int zzi) {
float myNum = (zzi + 2);
myNum = myNum / 3;
int precision = 100; // keep 4 digits
myNum = (float) (Math.floor(myNum * precision + .5) / precision);
return myNum;
}
Thanks before.
Your question is not so much about rounding a number as it is about rounding a display or String representation of a number. The solution:
Use new DecimalFormat("0.00");
Or String.format("%.2f", myNumber);
Or new java.util.Formatter("%.2f", myNumber);
Or System.out.printf("%.2f", myNumber);
Note: avoid use of float whenever possible, and instead prefer use of double which greatly improves numeric precision at little cost. For financial calculations use neither but instead opt for integer calculations or use BigDecimal.
Remember:
1) printing the number displaying two decimal places is very different from rounding the actual value. In other words "representation" != actual value.
2) floating point values are always imprecise. Even with rounding, you may or may not get an "exact value".
Having said that, the simplest approach is:
float myNum = ((123.456 * 100.0) + .5) / 100.0;
new DecimalFormat("#.##").format(myNum );
You can use DecimalFormat
System.out.println(new DecimalFormat("0.00").format(xFunction(94)));
You should work on the printing function. I assume you are using a System.out.println: replace it with
System.out.format("%.2f", numberToPrint);
Read the docs for that function to discover more about format strings.
I came across a strange corner of Java.(It seems strange to me)
double dd = 3.5;
float ff = 3.5f;
System.out.println(dd==ff);
o/p: true
double dd = 3.2;
float ff = 3.2f;
System.out.println(dd==ff);
o/p: false
I observed that if we compare any two values (a float and a double as I mentioned in the example) with .5 OR .0 like 3.5, 234.5, 645.0
then output is true i.e. two values are equal otherwise output is false though they are equals.
Even I tried to make method strictfp but no luck.
Am I missing out on something.
Take a look at What every computer scientist should know about floating point numbers.
Squeezing infinitely many real numbers into a finite number of bits requires an approximate representation....
--- Edit to show what the above quote means ---
You shouldn't ever compare floats or doubles for equality; because, you can't really guarantee that the number you assign to the float or double is exact.
So
float x = 3.2f;
doesn't result in a float with a value of 3.2. It results in a float with a value of 3.2 plus or minus some very small error. Say 3.19999999997f. Now it should be obvious why the comparison won't work.
To compare floats for equality sanely, you need to check if the value is "close enough" to the same value, like so
float error = 0.000001 * second;
if ((first >= second - error) || (first <= second + error)) {
// close enough that we'll consider the two equal
...
}
The difference is that 3.5 can be represented exactly in both float and double - whereas 3.2 can't be represented exactly in either type... and the two closest approximations are different.
Imagine we had two fixed-precision decimal types, one of which stored 4 significant digits and one of which stored 8 significant digits, and we asked each of them to store the number closest to "a third" (however we might do that). Then one would have the value 0.3333 and one would have the value 0.33333333.
An equality comparison between float and double first converts the float to a double and then compares the two - which would be equivalent to converting 0.3333 in our "small decimal" type to 0.33330000. It would then compare 0.33330000 and 0.33333333 for equality, and give a result of false.
floating point is a binary format and it can represent numbers as a sum of powers of 2. e.g. 3.5 is 2 + 1 + 1/2.
float 3.2f as an approximation of 3.2 is
2 + 1 + 1/8+ 1/16+ 1/128+ 1/256+ 1/2048+ 1/4096+ 1/32768+ 1/65536+ 1/524288+ 1/1048576+ 1/4194304 + a small error
However double 3.2d as an approximation of 3.2 is
2 + 1 + 1/8+ 1/16+ 1/128+ 1/256+ 1/2048+ 1/4096+ 1/32768+ 1/65536+ 1/524288+ 1/1048576+ 1/8388608+ 1/16777216+ 1/134217728+ 1/268435456+ 1/2147483648+ 1/4294967296+ 1/34359738368+ 1/68719476736+ 1/549755813888+ 1/1099511627776+ 1/8796093022208+ 1/17592186044416+ 1/140737488355328+ 1/281474976710656+ 1/1125899906842624 + a smaller error
When you use floating point, you need to use appropriate rounding. If you use BigDecimal instead (and many people do) it has rounding built in.
double dd = 3.2;
float ff = 3.2f;
// compare the difference with the accuracy of float.
System.out.println(Math.abs(dd - ff) < 1e-7 * Math.abs(ff));
BTW the code I used to print the fractions for double.
double f = 3.2d;
double f2 = f - 3;
System.out.print("2+ 1");
for (long i = 2; i < 1L << 54; i <<= 1) {
f2 *= 2;
if (f2 >= 1) {
System.out.print("+ 1/" + i);
f2 -= 1;
}
}
System.out.println();
The common implementation of floating point numbers, IEEE754, allows for the precise representation of only those numbers which have a short, finite binary expansion, i.e. which are a sum of finitely many (nearby) powers of two. All other numbers cannot be precisely represented.
Since float and double have different sizes, the representation in both types for a non-representable value are different, and thus they compare as unequal.
(The length of the binary string is the size of the mantissa, so that's 24 for float, 53 for double and 64 for the 80-bit extended-precision float (not in Java). The scale is determined by the exponent.)
This should work:
BigDecimal ddBD = new BigDecimal(""+dd);
BigDecimal ffBD = new BigDecimal(""+ff);
// test for equality
ddBO.equals(ffBD);
Always work with BigDecimal when you want to compare floats or doubles
and always use the BigDecimal constructor with the String parameter!
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
int totalOptCount = 500;
int totalRespCount=1500;
float percentage =(float)(totalOptCount/totalRespCount);
Why does this always return value 0.0? Also I want to format this into 00.00 format and convert into string?
Because the conversion to float happens after the division has been done. You need:
float percentage = ((float) totalOptCount) / totalRespCount;
You should be able to format using something like:
String str = String.format("%2.02f", percentage);
If you are using int values, using a double may be a better choice and have less rounding error. float can represent int values without error up to ~16 million. double can accurately represent all int values.
double percentage =(double) totalOptCount / totalRespCount;
Percentages are usually multiplied by 100, meaning you can drop the cast.
double percentage = 100.0 * totalOptCount / totalRespCount;
(totalOptCount/totalRespCount)
here both dividend and divisor are of type int which means they will allow only integer values and the answer of such equation will always be an integer literal.
if I break this it will be something like below
(double)(500/1500)
According to the actual calculation, 500/1500 will give you 0.33333 but compiler will convert this into integer literal because both operands are of type int
(double)(0)
Compiler gets an instruction to cast this 0 value to double so you got 0.0 as result
0.0
and then you can change the result to any format as suggeted by #Zach Janicki.
keep in mind if both the operands are of same type than result will be of same type too.
Integer division (which includes long, short, byte, char, int) in Java always returns an int (or long, if one of the parameters is long), rounding towards zero. Your conversion occurs after this calculation.
(The formatting question is already answered by the other answers - alternatively you could also have a look at java.text.NumberFormat, specially java.text.DecimalFormat.)
String.format("%2.02f", (float)totalOptCount/totalRespCount);
to format a double and print out as a percentage, you can use use
System.out.println(new DecimalFormat("##.##").format(yourDouble) + "%"));