the Javadoc of java.lang.Math.pow(double a, double b) states:
If the first argument is finite and less than zero:
if the second argument is finite and not an integer, then the result is NaN.
This means a call to Math.pow(-Math.E,-1.1d) yields NaN.
Why isn't Math.pow() returning the inverse 1/e^1.1? Is there an error in my reasoning?
Thanks!
Yes, there's an issue with your logic. Please go and read about complex numbers.
The problem is that a negative base raised to a non-integer negative power results in a complex number, not a real double. There's an imaginary part that Math.pow can't deal with.
Yes, why it should return 1/e^1.1? This will be 1/(-e)^1.1 which is not real number.
Related
Math.pow(-27.0, 1.0/3) should be equivalent to cbrt(-27) which does return -3. Why does pow return NaN?
It is not integer division and it is not me, I can not think of a reason this should happen.
According to Oracle, one of the special cases for Math.pow(double,double) method is:
If the first argument is finite and less than zero and the second
argument is finite and not an integer, then the result is NaN.
And Math.cbrt(double) works because:
For positive finite x, cbrt(-x) == -cbrt(x); that is, the cube root of
a negative value is the negative of the cube root of that value's
magnitude
It doesn't return an error. I highly recommend you read through the rules given in the Math.pow(double, double) Javadoc. I'll help the first argument is finite and less than zero and the second argument is finite and not an integer, then the result is NaN.
You cannot take the cube root of -27 rationally because it is negative, which explains why math.pow returns NAN. Cbrt(-27) returns -3 because it works a little differently: it takes the magnitude of the value (in this case, ||-27|| = 27), calculates and then reapplies the negative, giving you -3.
What kind of rounding is Math.round(arg)?
It does not fully/exactly fint into any of RoundingMode constants. But this question is not about RoundingMode constants. It is about all principal ways how rounding can be done and is done (most widely used practice).
So what wikipedia category does it fully fits into? What exact term to use to describe this way of rounding?
All kinds of rounding (wiki)
THIS QUESTION IS DIFFERENT FROM What RoundingMode constant works 100% like Math.round? BECAUSE THIS QUESTION IS ASKING ABOUT GENERALLY ACCEPTED MATHEMATICAL NAME OF Math.round() METHOD (as wikipedia defines it, for example), WHILE MENTIONED QUESTION IS ONLY ABOUT SPECIFIC CONSTANTS IN RoundingMode class.
As found in the official documentation:
public static long round(double a)
Returns the closest long to the argument, with ties rounding up.
Special cases:
If the argument is NaN, the result is 0.
If the argument is negative infinity or any value less than or equal to the value of Long.MIN_VALUE, the result is equal to the value
of Long.MIN_VALUE.
If the argument is positive infinity or any value greater than or equal to the value of Long.MAX_VALUE, the result is equal to the value
of Long.MAX_VALUE.
Parameters:
a - a floating-point value to be rounded to a long. Returns:
the value of the argument rounded to the nearest long value.
See Also:
Long.MAX_VALUE, Long.MIN_VALUE
So to keep it simple: It uses RoundingMode.HALF_UP for positive numbers and RoundingMode.HALF_DOWN for negative numbers. It always goes towards infinity.
There's enough information in the table of rounding modes you linked to to figure this out if you call Math.round on each of the values in the Value column and note the outputs. Here they are in Java REPL:
As you can see, those results match the round to nearest Round half up (towards +∞) column in the table.
In my Android app I am trying to evaluate the expression: (-2^(x)) but can't seem
to get the Math.pow() method from the JAVA library to work. I am able to evaluate (2^(x)) but not the other with negative base.
Here is a look at the Logs. The y values are all returned as NaN.
to evaluate I am using the following statements:
double result = Math.pow(x,exponent);
result = coefficient * result;
I don't know what might seem to be the problem. Perhaps is the way the negative base is set up.
thanks for any advice
return multiplier * Math.pow(base,result);
Assuming that you are trying to compute (-2) to the power x, where x is one of the x values shown in the image: this does not work unless x is an integer. The reason is that the answer is not a real number. (For example, what is (-1)^0.5? That's the square root of -1, which is i, an imaginary number, not a real number.) The x values shown in the image are all non-integers (there appear to be some that are very close to integers but still aren't--there's a non-zero in the last decimal place). Thus, the results all come out as NaN.
This is explicit in the javadoc for Math.pow:
If the first argument is finite and less than zero:
if the second
argument is a finite even integer, the result is equal to the result
of raising the absolute value of the first argument to the power of
the second argument
if the second argument is a finite odd integer,
the result is equal to the negative of the result of raising the
absolute value of the first argument to the power of the second
argument
if the second argument is finite and not an integer, then the
result is NaN.
If what you're doing is something other than (-2)^x, then your question is confusing and needs clarification.
A negative base with a fractional exponent is a complex number with a real and imaginary part. The Math.pow function is not equipped to return a complex number; a double return value can't represent or refer to a complex value.
The problem happens because of the way all languages represent floating point numbers. You can no more represent 0.1 exactly as a binary number than you can 1/3 using base 10.
double r = 11.631;
double theta = 21.4;
In the debugger, these are shown as 11.631000000000000 and 21.399999618530273.
How can I avoid this?
These accuracy problems are due to the internal representation of floating point numbers and there's not much you can do to avoid it.
By the way, printing these values at run-time often still leads to the correct results, at least using modern C++ compilers. For most operations, this isn't much of an issue.
I liked Joel's explanation, which deals with a similar binary floating point precision issue in Excel 2007:
See how there's a lot of 0110 0110 0110 there at the end? That's because 0.1 has no exact representation in binary... it's a repeating binary number. It's sort of like how 1/3 has no representation in decimal. 1/3 is 0.33333333 and you have to keep writing 3's forever. If you lose patience, you get something inexact.
So you can imagine how, in decimal, if you tried to do 3*1/3, and you didn't have time to write 3's forever, the result you would get would be 0.99999999, not 1, and people would get angry with you for being wrong.
If you have a value like:
double theta = 21.4;
And you want to do:
if (theta == 21.4)
{
}
You have to be a bit clever, you will need to check if the value of theta is really close to 21.4, but not necessarily that value.
if (fabs(theta - 21.4) <= 1e-6)
{
}
This is partly platform-specific - and we don't know what platform you're using.
It's also partly a case of knowing what you actually want to see. The debugger is showing you - to some extent, anyway - the precise value stored in your variable. In my article on binary floating point numbers in .NET, there's a C# class which lets you see the absolutely exact number stored in a double. The online version isn't working at the moment - I'll try to put one up on another site.
Given that the debugger sees the "actual" value, it's got to make a judgement call about what to display - it could show you the value rounded to a few decimal places, or a more precise value. Some debuggers do a better job than others at reading developers' minds, but it's a fundamental problem with binary floating point numbers.
Use the fixed-point decimal type if you want stability at the limits of precision. There are overheads, and you must explicitly cast if you wish to convert to floating point. If you do convert to floating point you will reintroduce the instabilities that seem to bother you.
Alternately you can get over it and learn to work with the limited precision of floating point arithmetic. For example you can use rounding to make values converge, or you can use epsilon comparisons to describe a tolerance. "Epsilon" is a constant you set up that defines a tolerance. For example, you may choose to regard two values as being equal if they are within 0.0001 of each other.
It occurs to me that you could use operator overloading to make epsilon comparisons transparent. That would be very cool.
For mantissa-exponent representations EPSILON must be computed to remain within the representable precision. For a number N, Epsilon = N / 10E+14
System.Double.Epsilon is the smallest representable positive value for the Double type. It is too small for our purpose. Read Microsoft's advice on equality testing
I've come across this before (on my blog) - I think the surprise tends to be that the 'irrational' numbers are different.
By 'irrational' here I'm just referring to the fact that they can't be accurately represented in this format. Real irrational numbers (like π - pi) can't be accurately represented at all.
Most people are familiar with 1/3 not working in decimal: 0.3333333333333...
The odd thing is that 1.1 doesn't work in floats. People expect decimal values to work in floating point numbers because of how they think of them:
1.1 is 11 x 10^-1
When actually they're in base-2
1.1 is 154811237190861 x 2^-47
You can't avoid it, you just have to get used to the fact that some floats are 'irrational', in the same way that 1/3 is.
One way you can avoid this is to use a library that uses an alternative method of representing decimal numbers, such as BCD
If you are using Java and you need accuracy, use the BigDecimal class for floating point calculations. It is slower but safer.
Seems to me that 21.399999618530273 is the single precision (float) representation of 21.4. Looks like the debugger is casting down from double to float somewhere.
You cant avoid this as you're using floating point numbers with fixed quantity of bytes. There's simply no isomorphism possible between real numbers and its limited notation.
But most of the time you can simply ignore it. 21.4==21.4 would still be true because it is still the same numbers with the same error. But 21.4f==21.4 may not be true because the error for float and double are different.
If you need fixed precision, perhaps you should try fixed point numbers. Or even integers. I for example often use int(1000*x) for passing to debug pager.
Dangers of computer arithmetic
If it bothers you, you can customize the way some values are displayed during debug. Use it with care :-)
Enhancing Debugging with the Debugger Display Attributes
Refer to General Decimal Arithmetic
Also take note when comparing floats, see this answer for more information.
According to the javadoc
"If at least one of the operands to a numerical operator is of type double, then the
operation is carried out using 64-bit floating-point arithmetic, and the result of the
numerical operator is a value of type double. If the other operand is not a double, it is
first widened (§5.1.5) to type double by numeric promotion (§5.6)."
Here is the Source
I have a problem with dividing a long value by 1000 and round it to an integer.
My long value is: 1313179440000
My code is
long modificationtime = 1313179440000;
Math.round(modificationtime/1000l)
If i print out the divided and formated value, it returns me:
1313179392
so.
value : 1313179440000
expected: 1313179440
got : 1313179392
I do not know why this happens.
Can anybody help me?
best regards,
prdatur
Math.round(float) is being used. A float has a larger range than a long, but it cannot represent all integers within that range -- in this case the integer 1313179440 (the original result of the division) lies in the part of the range that exceeds integer precision.
Don't use Math.round as it's not needed (input is already an integer!), or;
Use Math.round(double), as in: Math.round(modificationTime/1000d). Note that the divisor is a double and thus the dividend (and the result) of the expression are also promoted to double.
Happy coding.
The reason you get that result is that Math.Round() accepts either a double. Since your number isn't exactly representable as a double, the closest number that is gets passed in.
Note that round() is completely unnecessary here. modificationTime/1000l requires no rounding. If you do require rounding, change the argument to modificationTime/1000d.