Java double calculation problems [duplicate] - java

This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 6 years ago.
I'm currently working on a Trafficsimulation which is based on a grid system. For some reason the line of code, which calculates how many tiles i have to add always returns 0. I have tried it without the variables but it still doesn't work.
double blocksToAdd = o.getVelocity()*((1000/Main.FPS)/1000);
Currently the velocity is equal to 1.0f and the Simulation runs at 10 FPS, so blocksToAdd should be 0.1, but it always returns 0.

Since Main.FPS is an int, 1000/Main.FPS is also an int, equal to 100. You then proceed to calculate 100/1000. Since this is an integer division, only the "whole" part is taken, giving 0.
Using floating point literals will cause Java to use floating point division, which should produce the correct result:
double blocksToAdd = o.getVelocity() * ((1000.0 /Main.FPS ) / 1000.0);
// Here --------------------------------------^--------------------^

Most likely due to integer division tuncating the fraction.
Replace the first 1000 with 1000.0 and all will be well. (The latter is a floating point double literal which causes the division to be computed in floating point.) There are other remedies but I find this one to be the clearest.

Related

Java - infinite while loop with float [duplicate]

This question already has answers here:
double or float datatype doesn't addup properly in a loop?
(5 answers)
Closed 6 years ago.
I am currently learnig java float-point numbers. I know, that a float have a specific amount of significant digets. I also know, that a float is represented in java like -1 or 1 * num * 10^x. Where num is the numer and 10^x is the decimal "point". But here we do not have a fraction of a number. How is a infinite loop here possible?
The code with infinite loop:
float f = 123456789;
while (f-- > 0) {
System.out.println(f);
}
It's about floating point arithmetic. When you're decrementing the number you stumble upon the situation when you go through the number f = 1.23456792E8 makes everything go wrong, because f-1 and f have the same floating point representation here. So decrementing makes the number be itself, which leads to the infinite loop. Just check:
System.out.println(1.23456792E8f);
System.out.println(1.23456792E8f - 1);
What is so special about the number and why execution stops there? It's because the floating point representation of 123456789 is 1.23456792E8. Already this gives us a gap of at least 3 due to the lack of precision of floating point numbers. Using double instead of float makes the program finish, but the issue will occur with higher numbers.

Java 1029 / 9.8 = 104.999 [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
double test = 1029 / 9.8; // = 104.99999...
int inttest1 = (int) test; // 104
int inttest2 = (int)Math.floor(test); // 104
double testtt = 9.8 * 105; // 1029.0
1029 / 9.8 equals 105
but Java returns 104.9999...
More serious problem is integer casing result is 104, not 105
Why this happens and how can I avoid this result?
There are an infinite number of numbers, even in the limited range represented by Java. That's because mathematically, if you give me any two distinct numbers, I can average them to get a number between them. No matter how close they are.
And there are only a limited number of bits available to represent those numbers.
Hence, something has to give. What gives is the precision of the numbers. Not all numbers can be represented exactly, so some (the vast majority actually) are approximations.
For example, 0.1 cannot be represented exactly with IEEE754 encoding, even with a billion bits available to you.
See this answer for more information on the inherent imprecision of limited-storage floating point numbers.
Casting to an int implicitly drops any decimal. No need to call Math.floor() (assuming positive numbers)
To avoid this behavior use BigDecimal;
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
Standard floating point variables are in binary floating point. Many decimal floating point values (which are the ones you type in your code) have no exact representation in binary floating point. So it isn't doing the calculation with the exact numbers you entered but with some values very close to it. You can use Math.round to round the result to the precision you need and most likely the small error will disappear.
If you really need exact decimal calculation use BigDecimal but note that it is much slower.

odd results with double precision in Java [duplicate]

This question already has answers here:
Why can't decimal numbers be represented exactly in binary?
(22 answers)
Floating point arithmetic not producing exact results [duplicate]
(7 answers)
Closed 9 years ago.
I'm simply trying to calculate percentage_imp, but instead of 0.22 (exactly 0.22, no rounding error), I get 0.22000000000000003!!
I used to get similar odd results, and I've been told to move from float to double, but this one is still odd!
All the variables below are double!
double percentage_imp= budget - (sum_minlessi)/ (sum_i + sum_lessi);
Thats because of the floating point precision values.
You must read:- What Every Computer Scientist Should Know About Floating-Point Arithmetic
You must also read how floating point arithmetic and its internal representation works.
0.22 is not representable as a double.
As an example, 1/3 cannot be represented in base-10, so we approximate with 0.3333333333333333.
Its a rounding error inherit in binary calculations. Not all rational decimal numbers can be represented as a single decimal number in binary. As such, when you perform operations such as multiply and divide, you'll get some nasty error on the last few digits.
Moving from double to float doesn't change this as double is simply a double precision floating point number.
I suggest you look at this link
As a extra bonus in java, simple operations such as binary multiplications are optimized as much as possible utilizing any sort of hardware optimizations when possible yielding different answers on different machines. If you require consistent behavior across all machines use the strictfp keyword in your class declaration.

Double always returns 0 when dividing ints [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Dividing by 100 returns 0
(6 answers)
Closed 9 years ago.
Would someone mind explaining why this doesn't work? All variables except for chance are ints, whereas chance is a double. When I print all the values they are definitely correct... but chance always comes out as 0.0. I know this has something to do with converting ints to doubles, as I have had an issue like this a couple of times before. What is the key to getting it to do what you want?
gladValue = (glad.dexterity+glad.tactical+weaponSkill);
oppValue = (glad.target.dexterity+glad.target.tactical+glad.target.agility);
chance = (gladValue/oppValue)*10.0;
Thanks
You should write gladValue * 10.0 / oppValue instead.
The reason is quite subtle. Your brackets mean that gladValue / oppValue is computed first. But these variables are integers so the result is an integer and therefore you lose the fraction part. Only when it is multipled by 10.0 will it get promoted to a double; but by then it's too late.
If you do as I say then, bearing mind that * and / have the same precedence and the operations happen from left to right, then when computing gladValue * 10.0, gladValue is promoted to floating point and that floating point result is divided by oppValue.

Floating point multiplication in java [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to round a number to n decimal places in Java
When multiplying two numbers in java happens this:
double a = 9.495 * 100;
Expected result:
a = 949.5;
But the obtained result is:
a = 949.4999999999999
When I try to round number 9.495 in two decimal places the result is 9.49 instead of 9.50
Any ideas how to solve this problem?
If you want accurate floating point computations, do not use the float or double types, but rather make use of the BigDecimal class.
This is a side effect of floating point calculations, and is well understood, but not necessarily intuitive. This question has actually been asked literally thousands of times, and you need to study how floating point arithmetic works.
To get around this, if you only need 2-decimal precision, then use a integer instead.
For example, if you're dealing with currency, and you want to buy a 100 items for $4.95, then you represent the cost of that value as the integer "495", an multiply that by 100, which gives you "49500". You always treat the last two digits as cents, so "49500" is $495.00.
You cannot. Floating point and double precision numbers in a computer cannot represent all possible values.

Categories