Not able to compute value of negative base in JAVA - java

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.

Related

Math.pow(-27.0,1.0/3) returns NaN

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)`? What exact term to use to describe this way of rounding?

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.

Why does nextUp method in Math class skips some values?

I was just messing around with this method to see what it does. I created a variable with value 3.14 just because it came to my mind at that instance.
double n = 3.14;
System.out.println(Math.nextUp(n));
The preceding displayed 3.1400000000000006.
Tried with 3.1400000000000001, displayed the same.
Tried with 333.33, displayed 333.33000000000004.
With many other values, it displays the appropriate value for example 73.6 results with 73.60000000000001.
What happens to the values in between 3.1400000000000000 and 3.1400000000000006? Why does it skips some values? I know about the hardware related problems but sometimes it works right. Also even though it is known that precise operations cannot be done, why is such method included in the library? It looks pretty useless due to the fact that it doesn't work always right.
One useful trick in Java is to use the exactness of new BigDecimal(double) and of BigDecimal's toString to show the exact value of a double:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
System.out.println(new BigDecimal(3.14));
System.out.println(new BigDecimal(3.1400000000000001));
System.out.println(new BigDecimal(3.1400000000000006));
}
}
Output:
3.140000000000000124344978758017532527446746826171875
3.140000000000000124344978758017532527446746826171875
3.1400000000000005684341886080801486968994140625
There are a finite number of doubles, so only a specific subset of the real numbers are the exact value of a double. When you create a double literal, the decimal number you type is represented by the nearest of those values. When you output a double, by default, it is shown as the shortest decimal fraction that would round to it on input. You need to do something like the BigDecimal technique I used in the program to see the exact value.
In this case, both 3.14 and 3.1400000000000001 are closer to 3.140000000000000124344978758017532527446746826171875 than to any other double. The next exactly representable number above that is 3.1400000000000005684341886080801486968994140625
Floating point numbers are stored in binary: the decimal representation is just for human consumption.
Using Rick Regan's decimal to floating point converter 3.14 converts to:
11.001000111101011100001010001111010111000010100011111
and 3.1400000000000006 converts to
11.0010001111010111000010100011110101110000101001
which is indeed the next binary number to 53 significant bits.
Like #jgreve mentions this has to do due to the use of float & double primitives types in java, which leads to the so called rounding error. The primitive type int on the other hand is a fixed-point number meaning that it is able to "fit" within 32-bits. Doubles are not fixed-point, meaning that the result of double calculations must often be rounded in order to fit back into its finite representation, which leads sometimes (as presented in your case) to inconsistent values.
See the following two links for more info.
https://stackoverflow.com/a/322875/6012392
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
A work around could be the following two, which gives a "direction" to the first double.
double n = 1.4;
double x = 1.5;
System.out.println(Math.nextAfter(n, x));
or
double n = 1.4;
double next = n + Math.ulp(n);
System.out.println(next);
But to handle floating point values it is recommended to use the BigDecimal class

Power of a negative decimal raised to a decimal

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.

Processing - rule of cosines (sss) - NaN

I am working on a simple inverse kinematic delta robot controller with Processing. I am stuck at the rule of cosines. I have the length of the three sides and wish to get the angles. But float angle = acos((sq(humerus)+sq(ulna) - sq(radius))/(2 * humerus * ulna));
always returns NaN. Any ideas?
You'll probably want to use the law of cosines if you know the sides:
In Java terms, to solve for the angle C (opposite to side of length c) we would have
Math.acos((a*a + b*b - c*c) / (2*a*b))
There are a couple reasons why you could be getting NaN:
One of your side lengths is negative, so when you square root it you receive NaN.
Your triangle can't really exist based on the side lengths you specified. Look at this documentation for acos:
If the argument is NaN or its absolute value is greater than 1, then the result is NaN.
If you check the javadoc for Math.acos, you see the following:
If the argument is NaN or its absolute value is greater than 1, then the result is NaN.
So, there are two possibilities:
The numerator is greater than the denominator in absolute value, resulting in a fraction that exceeds 1.0. The arccosine will therefore return a NaN.
One of the square roots is returning a NaN. As we see from the javadoc: If the argument is NaN or less than zero, then the result is NaN.
So, I would check your values for humerus, radius and ulna. It's possible that you either allowed a slightly too large numerator (e.g., via floating point error) or you had a vector rather than a scalar value for your arm bone measurements (resulting in a negative rather than a positive argument to square root).

Categories

Resources