I am trying to do following calculation in my java class
Math.pow (0.0901 / 12 * (1 + 0.0901 / 12), 356.966667)
I am getting 0.0 as the result. However the expected result is 0.10844
I am not so sure that your result should be 0.10844. The base number is something like this ~0.00756 and you raise it to a positive power of ~357. This means that for such a big power, you will have many more zeroes after the decimal point. This means you will have a positive value smaller that the one double can store and it will be rounded to 0.0.
Using BigDecimal you will get the following value: ~7.08E-756 for your computation while the smallest positive double value (Double.MIN_VALUE) is 4.9E-324. This means that 0.0 will be your rounded value.
Related
Hay,
I want to round a number two digits after the decimal point only by using this mathematic formula:
For example the number 831.38849 should be rounded to 831.39 and printed out. I have tried something like this, but it didn't work: 0.01 * (100 * number + 0.5)
I know that similar questions have been asked before, but I'm not allowed to use all the fancy and easy stuff for this task like Math.round, BigDecimal, etc
⌊ ⌋ are math symbols for the floor function1, 2, 3
So the correct implementation of the mathematic formula
is the following Java code:
Math.floor(100d * number + 0.5) / 100d
Note: 100d can also be written 100.0, 100., or simply 100 (assuming number is a double)
So, the fancy part is handled by casting your floating point number to an integral value. You want to eliminate the portion two places to the right of the decimal, so you first multiply it by 100 to shift the decimal, add the 0.5 to round up anything 0.5 or higher, cast to an int (or a long) to truncate it, then divide by 100 to shift the decimal point back.
[Edit -- Adding condition to handle negatives, so it meets definition of "floor".]
double original_number = 831.38849;
double rounded_number = (original_number >= 0)
? ((long) (original_number * 100 + 0.5)) / 100.0
: ((long) (original_number * 100 - 0.5)) / 100.0;
Why I am getting -0.0 when 0.0 multiplied by -1???
I have taken 0.0 as float
sign=-1;
float output=0.0;
JOptionPane.showmessagedialog(null,0.0*sign);
the output shown in -0.0 instead of 0
This is an answer taken from http://www.javawebtips.com/154041/
"-0.0" Is produced when a floating-point operation results in a negative floating-point number so close to 0 that cannot be represented normally.
-2.0 / Float.POSITIVE_INFINITY -> -0.0
"-0.0" Is numerically identical to "0.0". However, some operations involving "-0.0" are different than the same operation with "0.0".
(-0.0) == 0.0 -> true
2.0 / (0.0) - Infinity
2.0 / (-0.0) ->-Infinity
Floating point values have both positive and negative zero. It may seem quirky, but there's a good reason for it (given the representational limits of floating point numbers).
You might consider casting your result to an int if you would really like the answer to just be 0.
The zeros in Java floating point do not just represent the real number zero. They are used to represent every number whose absolute magnitude is too small to be represented as a non-zero number, every underflow result.
Similarly, the infinities represent not just the result of division by zero, but every result whose absolute magnitude is too big to be represented as a finite number, every overflow result.
Making zero signed permits distinction between positive underflow results and negative underflow results, including, as already stated in another answer, getting the correct infinity on division of a non-zero number by an underflow result.
I've been a little curious about this. Math.random() gives a value in the range [0.0,1.0). So what might the largest value it can give be? In other words, what is the closest double value to 1.0 that is less than 1.0?
Java uses 64-bit IEEE-754 representation, so the closest number smaller than one is theoretically 3FEFFFFFFFFFFFFF in hexadecimal representation, which is 0 for sign, -1 for the exponent, and 1.9999999999999997 for the 52-bit significand. This equals to roughly 0.9999999999999998.
References: IEEE-754 Calculator.
The number that you want is returned by Math.nextAfter(1.0, -1.0).
The name of the function is somewhat of a misnomer. Math.nextAfter(a, 1.0) returns the least double value that is greater than a (i.e., the next value after a), and Math.nextAfter(a, -1.0) returns the greatest value that is less than a (i.e., the value before a).
Note: Another poster said, 1.0-Double.MIN_NORMAL. That's wrong. 1.0-Double.MIN_NORMAL is exactly equal to 1.0.
The smallest positive value of a double is Double.MIN_NORMAL. So, the largest number less than 1.0 is 1.0-Double.MIN_NORMAL.
Double.MIN_NORMAL is equal to 2-1022, so the answer is still extremely close to 1.0. You'd have to print the value of 1.0-Double.MIN_NORMAL to 308 decimal places before you could see anything but a 9.
This method returns 'true'. Why ?
public static boolean f() {
double val = Double.MAX_VALUE/10;
double save = val;
for (int i = 1; i < 1000; i++) {
val -= i;
}
return (val == save);
}
You're subtracting quite a small value (less than 1000) from a huge value. The small value is so much smaller than the large value that the closest representable value to the theoretical result is still the original value.
Basically it's a result of the way floating point numbers work.
Imagine we had some decimal floating point type (just for simplicity) which only stored 5 significant digits in the mantissa, and an exponent in the range 0 to 1000.
Your example is like writing 10999 - 1000... think about what the result of that would be, when rounded to 5 significant digits. Yes, the exact result is 99999.....9000 (with 999 digits) but if you can only represent values with 5 significant digits, the closest result is 10999 again.
When you set val to Double.MAX_VALUE/10, it is set to a value approximately equal to 1.7976931348623158 * 10^307. substracting values like 1000 from that would required a precision on the double representation that is not possible, so it basically leaves val unchanged.
Depending on your needs, you may use BigDecimal instead of double.
Double.MAX_VALUE is so big that the JVM does not tell the difference between it and Double.MAX_VALUE-1000
if you subtract a number fewer than "1.9958403095347198E292" from Double.MAV_VALUE the result is still Double.MAX_VALUE.
System.out.println(
new BigDecimal(Double.MAX_VALUE).equals( new BigDecimal(
Double.MAX_VALUE - 2.E291) )
);
System.out.println(
new BigDecimal(Double.MAX_VALUE).equals( new BigDecimal(
Double.MAX_VALUE - 2.E292) )
);
Ouptup:
true
false
A double does not have enough precision to perform the calculation you are attempting. So the result is the same as the initial value.
It is nothing to do with the == operator.
val is a big number and when subtracting 1 (or even 1000) from it, the result cannot be expressed properly as a double value. The representation of this number x and x-1 is the same, because double only has a limited number of bits to represent an unlimited number of numbers.
Double.MAX_VALUE is a huge number compared to 1 or 1000. Double.MAX_VALUE-1 is generally equals to Double.MAX_VALUE. So your code roughly does nothing when substracting 1 or 1000 to Double.MAX_VALUE/10.
Always remember that:
doubles or floats are just approximations of real numbers, they are just rationals not equally distributed among the reals
you should use very carefully arithmetic operators between doubles or floats which are not close (there is many other rules such like this...)
in general, never use doubles or float if you need arbitrary precision
Because double is a floating point numeric type, which is a way of approximating numeric values. Floating point representations encode numbers so that we can store numbers much larger or smaller than we normally could. However, not all numbers can be represented in the given space, so multiple numbers get rounded to the same floating point value.
As a simplified example, we might want to be able to store values ranging from -1000 to 1000 in some small amount of space where we would normally only be able to store -10 to 10. So we could round all values to the nearest thousand and store them in the small space: -1000 gets encoded as -10, -900 gets encoded as -9, 1000 gets encoded as 10. But what if we want to store -999? The closest value we can encoded is -1000, so we have to encode -999 as the same value as -1000: -10.
In reality, floating point schemes are much more complicated than the example above, but the concept is similar. Floating point representations of numbers can only represent some of all the possible numbers, so when we have a number that can't be represented as part of the scheme, we have to round it to the closest representable value.
In your code, all values within 1000 of Double.MAX_VALUE / 10 automatically get rounded to Double.MAX_VALUE / 10, which is why the computer thinks (Double.MAX_VALUE / 10) - 1000 == Double.MAX_VALUE / 10.
The result of a floating point calculation is the closest representable value to the exact answer. This program:
public class Test {
public static void main(String[] args) throws Exception {
double val = Double.MAX_VALUE/10;
System.out.println(val);
System.out.println(Math.nextAfter(val, 0));
}
}
prints:
1.7976931348623158E307
1.7976931348623155E307
The first of these numbers is your original val. The second is the largest double that is less than it.
When you subtract 1000 from 1.7976931348623158E307, the exact answer is between those two numbers, but very, very much closer to 1.7976931348623158E307 than to 1.7976931348623155E307, so the result will be rounded to 1.7976931348623155E307, leaving val unchanged.
How can we use them in our codes, and what will cause NaN(not a number)?
Positive infinity means going to infinity in the positive direction -- going into values that are larger and larger in magnitude in the positive direction.
Negative infinity means going to infinity in the negative direction -- going into values that are larger and larger in magnitude in the negative direction.
Not-a-number (NaN) is something that is undefined, such as the result of 0/0.
And the constants from the specification of the Float class:
Float.NEGATIVE_INFINITY
Float.POSITIVE_INFINITY
Float.NaN
More information can be found in the IEEE-754 page in Wikipedia.
Here's a little program to illustrate the three constants:
System.out.println(0f / 0f);
System.out.println(1f / 0f);
System.out.println(-1f / 0f);
Output:
NaN
Infinity
-Infinity
This may be a good reference if you want to learn more about floating point numbers in Java.
Positive Infinity is a positive number so large that it can't be represented normally. Negative Infinity is a negative number so large that it cannot be represented normally. NaN means "Not a Number" and results from a mathematical operation that doesn't yield a number- like dividing 0 by 0.
In Java, the Double and Float classes both have constants to represent all three cases. They are POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN.
Plus consider this:
double a = Math.pow(10, 600) - Math.pow(10, 600); //==NaN
Mathematically, everybody can see it is 0. But for the machine, it is an "Infinity" - "Infinity" (of same Rank), which is indeed NaN.
1/0 will result in positive infinity.
0/0 will result in Nan. You can use NaN as any other number, eg: NaN+NaN=NaN, NaN+2.0=NaN
-1/0 will result in negative infinity.
Infinity (in java) means that the result of an operation will be such an extremely large positive or negative number that it cannot be represented normally.
The idea is to represent special numbers which can arise naturally from operations on "normal" numbers. You could see infinity (both positive and negative) as "overflow" of the floating point representation, the idea being that in at least some conditions, having such a value returned by a function still gives meaningful result. They still have some ordering properties, for example (so they won't screw sorting operations, for example).
Nan is very particular: if x is Nan, x == x is false (that's actually one way to test for nan, at least in C, again). This can be quite confusing if you are not used to floating point peculiarities. Unless you do scientific computation, I would say that having Nan returned by an operation is a bug, at least in most cases that come to mind. Nan can come for various operations: 0/0, inf - inf, inf/inf, 0 * inf. Nan does not have any ordering property, either.
You can use them as any other number:
e.g:
float min = Float.NEGATIVE_INFINITY;
float max = Float.POSITIVE_INFINITY;
float nan = Float.NaN;
Positive Infinity is a positive number so large that it can't be
represented normally. Negative Infinity is a negative number so large
that it cannot be represented normally. NaN means "Not a Number" and
results from a mathematical operation that doesn't yield a number-
like dividing 0 by 0.
this is not a complete answer(or not clarified enough) - consider this:
double a = Math.pow(10,600) - Math.pow(10,600); //==NaN
mathematically everybody can see it is 0. but for the machine it is an "Infinity" - "Infinity"(of same order) witch is indeed NaN...