Reputation: 1154
When I try to take the N th root of a small number using C# I get a wrong number.
For example, when I try to take the third root of 1.07, I get 1, which is clearly not true.
Here is the exact code I am using to get the third root.
MessageBox.Show(Math.Pow(1.07,(1/3)).toString());
How do I solve this problem?
I would guess that this is a floating point arithmetic issue, but I don't know how to handle it.
Upvotes: 5
Views: 5401
Reputation: 25819
I'm pretty sure the "exact code" you give doesn't compile.
MessageBox.Show(Math.Pow(1.07,(1/3).toString()));
The call to toString is at the wrong nesting level, needs to be ToString, and (1/3) is integer division, which is probably the real problem you're having. (1/3) is 0 and anything to the zeroth power is 1. You need to use (1.0/3.0) or (1d/3d) or ...
Upvotes: 9
Reputation: 331
This may help in case you have a real nth root precision problem, but my experiance is that the builtin Math.Pow(double, int) is more precise:
private static decimal NthRoot(decimal baseValue, int N)
{
if (N == 1)
return baseValue;
decimal deltaX;
decimal x = 1M;
do
{
deltaX = (baseValue / Pow(x, N - 1) - x) / N;
x = x + deltaX;
} while (Math.Abs(deltaX) > 0);
return x;
}
private static decimal Pow(decimal a, int b)
{
if (b == 0) return 1;
if (a == 0) return 0;
if (b == 1) return a;
if (b % 2 == 0)
return Pow(a * a, b / 2);
else if (b % 2 == 1)
return a * Pow(a * a, b / 2);
return 0;
}
Upvotes: 1
Reputation: 68687
C# is treating the 1 and the 3 as integers, you need to do the following:
Math.Pow(1.07,(1d/3d))
or
Math.Pow(1.07,(1.0/3.0))
It is actually interesting because the implicit widening conversion makes you make a mistake.
Upvotes: 13
Reputation: 881443
First things first: if that's the exact code you're using, there's likely something wrong with your compiler :-)
MessageBox.Show(Math.Pow(1.07,(1/3).toString()));
will evaluate (1/3).toString() first then try and raise 1.07 to the power of that string.
I think you mean:
MessageBox.Show(Math.Pow(1.07,(1/3)).ToString());
As to the problem, (1/3) is being treated as an integer division returning 0 and n0 is 1 for all values of n.
You need to force it to a floating point division with something like 1.0/3.0
.
Upvotes: 3