Given following codes:
long testNum = 1000;
double midNum = testNum/60000;
System.out.println(midNum);
long another = Math.round(7600/midNum);
System.out.println(another);
The output is:
0.0
9223372036854775807
Why the first output is 0.0? How could I get the right result in java?
Since the first output is 0, why the next expression has an result? Shouldn't it throw out an by zero expression?
Why the first output is 0.0?
You are using integer division so this is the right result.
How could I get the right result in java?
Don't use integer division, use floating point instead, the simplest way to to make one of the value a floating point like this.
double midNum = testNum/60000.0;
or
double midNum = testNum/60e3;
Since the first output is 0, why the next expression has an result?
Floating point arithmetic uses IEEE-754 standard (sometimes called IEEE-753.99999999999998 ;)
In floating point, you never get an exception in Java, you might get infinity, negative infinity or NaN.
Integers don't have Infinity, or NaN and have no way to represent this, so it produced an Exception.
When you round any number too big for a long it gives you the closest presentable value which is Long.MAX_VALUE
BTW
long l = Math.round(Double.POSITIVE_INFINITY); // l == Long.MAX_VALUE
long l = Math.round(Double.NEGATIVE_INFINITY); // l == Long.MIN_VALUE
long l = (long) Double.NaN; // l == 0
From Double you might find this interesting.
public final class Double extends Number implements Comparable<Double> {
/**
* A constant holding the positive infinity of type
* {#code double}. It is equal to the value returned by
* {#code Double.longBitsToDouble(0x7ff0000000000000L)}.
*/
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
/**
* A constant holding the negative infinity of type
* {#code double}. It is equal to the value returned by
* {#code Double.longBitsToDouble(0xfff0000000000000L)}.
*/
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
/**
* A constant holding a Not-a-Number (NaN) value of type
* {#code double}. It is equivalent to the value returned by
* {#code Double.longBitsToDouble(0x7ff8000000000000L)}.
*/
public static final double NaN = 0.0d / 0.0;
/**
* A constant holding the largest positive finite value of type
* {#code double},
* (2-2<sup>-52</sup>)·2<sup>1023</sup>. It is equal to
* the hexadecimal floating-point literal
* {#code 0x1.fffffffffffffP+1023} and also equal to
* {#code Double.longBitsToDouble(0x7fefffffffffffffL)}.
*/
public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
long is can't hold decimals. Long is equal to int just with a higher range.
You should use decimal or float.
The reason your first result is 0.0 is due to your use of implicit casting. When dividing a long by a number, Java assumes that number is of the same type and will do "long" division, which has no remainder. Since 1000/60000 is between 0 and 1, the result is effectively floored to 0, and cast to 0.0 when it's a double. You can fix this by changing a line to double midNum = testNum/60000D;
Note the "D" at the end, indicating that 60000 is a double. This will force the long to be cast as a double and give the proper result.
For the second part, you're basically dividing by a very very small number, making it appear to be quite large. 0.0 cannot be represented accurately by a double, so you're actually dividing by something slightly above 0.0, which will be fixed when you fix the other part.
use type cast operator.
double midNum = (double)testNum/60000;
Related
I am trying to use java.lang.Math.IEEEremainder(double f1, double f2) in GWT. But I got below exception.
[ERROR] Line 1119: The method IEEEremainder(double, double) is
undefined for the type Math
I attempted to execute this code : angle = Math.IEEEremainder(angle, 360.0);
How to solve this issue in GWT?. If its not solve then what would be the alternative way to achieve the same functionality of Math.IEEEremainder this method.
According to the JRE Emulation this function is not supported in GWT.
So if you really need it and can't work around it, you will need to implement it yourself.
If I understand it correctly, you are trying to limit the angle to 360 degrees.
You could achieve that with this code:
/**
* Normalize a degree value.
* #param d value
* #return 0<=value<=360
*/
public static double normalizeDegrees(double d)
{
while (d < 0)
{
d += 360;
}
while (d > 360)
{
d -= 360;
}
return d;
}
If you just got positive numbers, you can even skip the upper while-Block.
If you really need to have the IEEEremainder method in GWT, implement it like that:
/**
* Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard. The remainder value is
* mathematically equal to <code>f1 - f2</code> × <i>n</i>, where <i>n</i> is the
* mathematical integer closest to the exact mathematical value of the quotient {#code f1/f2}, and if two
* mathematical integers are equally close to {#code f1/f2}, then <i>n</i> is the integer that is even. If the
* remainder is zero, its sign is the same as the sign of the first argument. Special cases:
* <ul>
* <li>If either argument is NaN, or the first argument is infinite, or the second argument is positive zero or
* negative zero, then the result is NaN.
* <li>If the first argument is finite and the second argument is infinite, then the result is the same as the first
* argument.
* </ul>
* #param f1 the dividend.
* #param f2 the divisor.
* #return the remainder when {#code f1} is divided by {#code f2}.
*/
public static double IEEEremainder(double f1, double f2)
{
double div = Math.round(f1 / f2);
return f1 - (div * f2);
}
(I added this as a new comment to show the syntax highlighting).
I have two float values:
float value1 = 1.9f;
float value2 = 20;
I want to multiply them and get an exact result, so I use BigDecimal and expect 38 as result:
BigDecimal total = new BigDecimal(value1).multiply(new BigDecimal(value2));
System.out.println(total); // 37.99999952316284179687500
When I do the same test with 10 and 1.9, I get 18.99999976158142089843750 instead of 19.
Why do I lose precision?
This is explained in the javadoc for the BigDecimal(double) constructor:
The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
And although your variables are floats, there is not ctor that takes floats, so they are cast as doubles. And like the docs say, if you used Strings for your values, you would get the exact result (38) you expect.
The error is right at the start:
float value1 = 1.9f;
You may think that value1 now contains exactly the value 1.9. But this is not the case. Floating point values are stored in binary. The important thing to remember is that some real values cannot be expressed by a finite sequence of digits, such as a float. 1.9 is such a number (just like in decimal the value 1.333... cannot be expressed by a finite sequence of digits).
So you should use BigDecimal from the start. Then the values can be exactly represented (because it is not stored in binary but in decimal) and the calculation results in the expected answer.
Let's say your value1 is a double as primitive type and want to output 2 decimal places and the value1 is 350. 4432567
double roundTotal = Math.round(value1 * 100.0) / 100.0;
or
double roundTotal = (double) Math.round(value1 * 100) / 100;
Output:
350.44
Note that the 2 digits precision. Zeros indicate the wanted number of decimal to display.
Example #2
double roundTotal = (double) Math.round(value1 * 10000) / 10000;
Output:
350.4432
You can use
Math.floor(float f);
//or
Math.ceil(float f);
functions for the exact value. Or you can override these functions for BigDecimal class.
I have a method that calculates the average
Note class:
private Double moyenneFinale;
#Column(name = "moyenne_finale")
public Double getMoyenneFinale() {
return this.moyenneFinale;
}
public void setMoyenneFinale(Double moyenneFinale) {
this.moyenneFinale = moyenneFinale;
}
Class calBean
private double result;
public double moyenneFinale;
public calNote {
result=0.0
result= ((100 * 20)/100)/45;
moyenneFinale=result;
note.setMoyenneFinale(moyenneFinale);
}
//getter and setter
the result should be 0.44
but recorded in the database given value is 0.0
if I make +1 it will be 1.0
All the numeric literals at ((100 * 20)/100)/45 are integers so each operation performs integer arithmetic instead floating pointer arithmetic and finally the result is cast to double at the assignation operation.
You should change at least one of your literals to 100.0, 20.0, 45.0, ...
In line
result= ((100 * 20)/100)/45;
you are using operator / on integers. When used on integers, operator / behaves as "DIV" (resulting integer). Examples: 10/4=2, but 10.0/4=2.5, 10/4.0=2.5, 10.0/4.0=2.5.
Options are:
To set numbers as 100.0, 20.0, 100.0 and 45.0. (It is enough to set just first one to 100.0).
result= ((100.0 * 20)/100)/45;
To use casting on numbers. (double)100.
result= (((double)100 * 20)/100)/45;
Or to add 1.0* before equation;
result= 1.0*((100 * 20)/100)/45;
Tho, first method is best in your case, second and third are useful if you are given integers x, y, z, t and your result is ((x * y)/z)/t;
I have some business logic with arithmetic expression and their results are as follows
(10.0 * 20.58)/1.0=205.7999..98
(6.0 * 37.9)/1.0=227.3999..98
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0
But expected results are
(10.0 * 20.58)/1.0=205.8
(6.0 * 37.9)/1.0=227.4
(5.0 * 50.0)/1.0=250.0
(10.0 * 37.9)/1.0=379.0
I am not clear why we are getting that .999..98 fraction part? Due to that my equals comparison is failing and so business logic. For few cases we are using
amt = (double)Math.round(orderAmt*100000)/100000;
But that is not possible to do the same in each and every place where we have double arithmetic expression.
I want to know why we get such results randomly and is there any possibility to round the results to 5 decimal places instead of rounding every where?
With radix 10 there are some fractions who can't be expressed exactly with a finite number of digits, like for example 1/3 = 0.33333333....
It's the same with radix 2, except that the dividers that produce this kind of results are not the one we are accustomed to, and for example, for 20.58, which is 2058 / 100, it is the case.
Internally, doubles and floats are stored with bits (an not digit), so the exact value of the double or float just can't be stored in the computer's memory. Each time you perform an operation with this value, you get a small shift, because of the approximation, which becomes visible when converting back to decimal format for printing.
It's something you have to pay attention while perfoming computations where precision is important.
So you have two solutions:
Store all your numbers in decimal type and perform all your calculation with it. This will achieve accuracy but for the price of performance.
You can also keep all the calculation with double or float, and format with a fixed number of digits only for printing results.
You could use BigDecimal for roundoff
BigDecimal bd = new BigDecimal((10.0 * 20.58)/1.0) ;
bd = bd.setScale(4, RoundingMode.UP);
use with a static method
public static double round(double value, int digits) {
BigDecimal bd = new BigDecimal(value);
return bd.setScale(digits, RoundingMode.UP).doubleValue();
}
RoundingMode has :
RoundingMode.UP;
RoundingMode.DOWN;
RoundingMode.HALF_DOWN;
RoundingMode.HALF_EVEN;
The basic problem is that
System.out.println(10.0 * 20.58);
prints
205.79999999999998
has a small rounding error due to a representation error in 20.58
You either need to
round the result before comparing.
use a comparision which allows for some error
use BigDecimal (which is over kill in most cases)
use cents instead of dollars i.e. use int or long with fixed precision.
In the last case, the same operation would read
System.out.println(10 * 2058);
prints
20580
where this is 100x the value you need as its fixed precision e.g. cents instead of dollars.
You may want to use double with rounding as below:
double roundingPlaces = 10.0;//use 10.0 for single decimal digit rounding
double a1 = 10.0;
double b1 = 20.58;
double c1 = 1.0;
System.out.println(Math.round((a1*b1*roundingPlaces)/c1)/roundingPlaces);
This prints 205.8.
float fa1 = (float) 10.0;
float fb1 = (float)20.58;
float fc1 = (float)1.0;
System.out.println(fa1*fb1/fc1);
This also prints 205.8
Use float instead of double
http://ideone.com/L9vwR8
System.out.println((float)((10.0f * 20.58f)/1.0f));
output
205.8
i have an Integer value:
Integer value = 56472201;
Where the value could be positive or negative.
When I divide the value by 1000000, I want this result in the form 56.472201 but instead it gives me just the quotient. How am I able to get both the quotient and remainder values?
cast it to float and then do it:
int i = 56472201;
float j = ((float) i)/1000000.0
Edit: Due to precision(needed in your case), use double. Also as pointed by Konrad Rudolph, no need for explicit casting:
double j = i / 1000000.0;
You have to convert the value to a floating point type first, otherwise you will be doing an integer division.
Example in C#:
int value = 56472201;
double decimalValue = (double)value / 1000000.0;
(The cast is actually not needed in this code, as dividing by a floating point number will cast the value to match, but it's clearer to write out the cast in the code as that is what actually happens.)
If you divide an int by a double you will be left with a double result as illustrated by this unit test.
#Test
public void testIntToDouble() throws Exception {
final int x = 56472201;
Assert.assertEquals(56.472201, x / 1e6d);
}
1e6d is 1 * 10^6 represented as a double