On my TI-84 Plus (Silver Edition), I can enter the following without error: (-1)^(1/3) = -1
I also know that entering some expressions like the following would yield a non-real -imaginary- number like: (-1)^.5
Now, my problem is with C#'s Math object. If I send any fractions like these: {1.667, 109.667, 0.667, 120.667} OR {4/3, 111/3, 2/3, 122/3}, I would get: {NaN, NaN, NaN, NaN}.
Do I have to write a new object MathHelper that checks the rational value and returns an answer according to a limited input switch? Or is there a feature to the Math object I am missing. I can do this on the calculator...
PS, I did not come across any similar questions online yet; so if this is a duplicate, please inform me ;)
[My new views]
Thank you all for your help! I had finished upgrading the "Microsoft.Solver.Foundation.dll" to the 4.0 targeted framework and it turned out that the 'Rational' object seemed to return only -1's and 'Indeterminate'. Then after entering (-1)^(1/2) [nonreal ans] on Google, it dawned on me that I was working with nth-roots!! So, it turned out that I had already managed imaginary numbers in the past in C#, hence having solved my problem:
Any even root 2n of a negative number -m will always equal an imaginary number i. (2n√-m)=i
I can't believe I forgot this simple algebra property
You will have to write your own Math helper to do functions like this (at least for Math.Pow). EDIT: Or you can use the Rational library like mentioned in the comments.
According to the documentation:
Input: x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity.
Result: NaN
Review the docs here: http://msdn.microsoft.com/en-us/library/system.math.pow.aspx
In C#, (-1)^R isn't defined for non-integer values of R.
If you try to calculate (-1)^(1/3), C# will calculate 1/3 first, resulting in a non-integer floating point number for R.
Solution:
Use the mathematical identity:
a^(x/y) = a^x * a^(1/y) x,y integers
For negative a, use:
a^1/y = -(|a|^1/y) // only works if y is odd
Or put together:
if (a < 0) {
if (y % 2 = 1) {
result = a^x * -1 * (-a)^(1.0/y); // Replace ^ with the correct C# call.
} else {
// NaN
}
} else {
result = a^(x/y);
}
Related
This is a Math question, but to try to solve a C# Programming issue so I am not sure if here is the best place for it.
In the following code, I can get the Derivative:
var x = 13.399E+153;
var d = ((1 + x) * (1 - x));
Console.WriteLine("d = {0:0}", d);
Console.ReadLine();
Where 13.399E+153; the 9's are recurring. But if x becomes:
var x = 14.00E+153;
I get -Infinity. I have done some research already but do not understand any possible solution.
URL: Mathematical function differentiation with C#?
also: Limit of the derivative of a function as x goes to infinity
I do understand why this is ocurring however:
If the limit of f(x) f(x) exists, there is a horizontal asymptote.
Therefore as the function approaches infinity it becomes more linear and
...thus the derivative approaches zero.
.
My question is, if I am returning the Derivative as a double for example, what would a solution be to prevent it being returned as Infinity? Should I return 1, or Zero?
if (double.IsInfinity(Derivative))
{
return ?;
}
You get the result of negative Infinity because the mathematical value of the result is less than the least value that can be represented using 64 bit floating point numbers. This is completely normal, I see nothing that needs to be fixed.
I just found out that when entering a negative x and a decimal y, Math.Pow() returns the not-defined value as result, which is wrong I guess. Calculating this in other programs, even like the windows Calculator works with a correct result. Also this case is not mentioned in the documentation.
Target Framework is 4.
Can anyone explain this?
The result is going to be complex number, so you have to use Complex class from System.Numerics namespace.
Complex n = new Complex(-2, 0);
Complex result = Complex.Pow(n, 1.1);
In case if result is real number (integer power), then you can use Math.Pow.
As #JeppeStigNielsen mentioned, the conversion from int/double to Complex is implicit, so the code can be shortened to:
Complex result = Complex.Pow(-2, 1.1);
Also this case is not mentioned in the documentation
You sure? From it's documentation;
Parameters
x < 0 but not NegativeInfinity; y is not an integer,
NegativeInfinity, or PositiveInfinity.
Return value
NaN
I'm not sure which OS you tried but it doesn't work in calc.exe (Win7 - 64bit) says Invalid Input.
As Ulugbek mentioned, taking 1.1 power of a negative value creates a complex number. Because (-2)1.1 = (-2)11/10 = (-2)1/1011 and getting 10 times rooth of -2 returns a complex number.
Since Math.Pow takes and returns double values, this doesn't fit with requirements. You can use Complex class from System.Numerics.
http://www.wolframalpha.com/input/?i=-2^1.1
Further reading: How is Math.Pow() implemented in .NET Framework?
I have the next function:
static bool isPowerOf(int num, int power)
{
double b = 1.0 / power;
double a = Math.Pow(num, b);
Console.WriteLine(a);
return a == (int)a;
}
I inserted the print function for analysis.
If I call the function:
isPowerOf(25, 2)
It return true since 5^2 equals 25.
But, if I call 16807, which is 7^5, the next way:
isPowerOf(16807, 5)
In this case, it prints '7' but a == (int)a return false.
Can you help? Thanks!
Try using a small epsilon for rounding errors:
return Math.Abs(a - (int)a) < 0.0001;
As harold suggested, it will be better to round in case a happens to be slightly smaller than the integer value, like 3.99999:
return Math.Abs(a - Math.Round(a)) < 0.0001;
Comparisons that fix the issue have been suggested, but what's actually the problem here is that floating point should not be involved at all. You want an exact answer to a question involving integers, not an approximation of calculations done on inherently inaccurate measurements.
So how else can this be done?
The first thing that comes to mind is a cheat:
double guess = Math.Pow(num, 1.0 / power);
return num == exponentiateBySquaring((int)guess, power) ||
num == exponentiateBySquaring((int)Math.Ceil(guess), power);
// do NOT replace exponentiateBySquaring with Math.Pow
It'll work as long as the guess is less than 1 off. But I can't guarantee that it will always work for your inputs, because that condition is not always met.
So here's the next thing that comes to mind: a binary search (the variant where you search for the upper boundary first) for the base in exponentiateBySquaring(base, power) for which the result is closest to num. If and only if the closest answer is equal to num (and they are both integers, so this comparison is clean), then num is a power-th power. Unless there is overflow (there shouldn't be), that should always work.
Math.Pow operates on doubles, so rounding errors come into play when taking roots. If you want to check that you've found an exact power:
perform the Math.Pow as currently, to extract the root
round the result to the nearest integer
raise this integer to the supplied power, and check you get the supplied target. Math.Pow will be exact for numbers in the range of int when raising to integer powers
If you debug the code and then you can see that in first comparison:
isPowerOf(25, 2)
a is holding 5.0
Here 5.0 == 5 => that is why you get true
and in 2nd isPowerOf(16807, 5)
a is holding 7.0000000000000009
and since 7.0000000000000009 != 7 => you are getting false. and Console.WriteLine(a) is truncating/rounding the double and only show 7
That is why you need to compare the nearest value like in Dani's solution
I am using C# inside .Net Environment. I have some really large integer values entered by user which are than divided by each other and the result is displayed. Now we know that 4/2 = 2 is simple but what if we divide
.0232321312321312312312312321032132139813912839013809123801283012983901283012380129382190381209382190382190382109382109382109312/ 1200000232323213213213213878978398494849023834902348239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048234902384902384902384902348239048239048234
The answer is like 1.93601056119411E-197
I want to display the answer as a full decimal/floating point value instead of relying on E symbol.
I wrote some code
using System.Numerics;
BigInteger x = BigInteger.Parse("0232321312321312312312312321032132139813912839013809123801283012983901283012380129382190381209382190382190382109382109382109312");
BigInteger y = BigInteger.Parse("1200000232323213213213213878978398494849023834902348239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048234902384902384902384902348239048239048234
")
BigInteger answer = BigInteger.Divide(x, y)
return answer.ToString("D")
I think that is what you are looking for, if you want the fractional part of the answer you'll have to do it all with the Complex type. Its not clear what you are doing from the question.
EDIT:
How about this
using System.Numerics;
BigInteger x = BigInteger.Parse("0232321312321312312312312321032132139813912839013809123801283012983901283012380129382190381209382190382190382109382109382109312");
BigInteger y = BigInteger.Parse("1200000232323213213213213878978398494849023834902348239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048239048234902384902384902384902348239048239048234
")
Complex answer = Complex.Divide((Complex)x, (Complex)y)
return answer.ToString("F50") //If 50 decimal places is enough.
I assume that you not only want to preceed your value with "0.00..." but also want to see the "missing" digits after 411.
If that is the case, then you cannot do this with floating point data types, since the floating point data types in .NET simply do not have the required precision. You will need to resort to external libraries, such as, for example, W3b.Sine (untested, just found it through a quick Google search), which allow for arbitrary-precision decimals.
I use .ToString("N0") that seems to do the job when I have the same problem.
If tan(x) = y and atan(y) = x why Math.Atan(Math.Tan(x)) != x?
I´m trying to calculate x in something like:
tan(2/x +3) = 5
so
atan(tan(2/x + 3) = atan(5)
and so on... but I´ve tried this:
double d = Math.Atan(Math.Tan(10));
and d != 10. Why?
The tangent function is periodic with period pi, and is invertible only if you restrict it to a subset of its domain over which it is injective. Usually the choice of such set is the open interval ]-pi/2, pi/2[, hence the arctan function will always return a point in that interval. In your case, 10 = 3*pi + 0.57522... Thus, the arctan of the tangent of 10 will return 0.57522...
Note that the arctan function, defined as above, is injective and defined over all the real numbers, hence the converse of your problem math.tan(math.atan(x)) == x
indeed holds for each x (except for numerical errors).
In order to deal with numerical errors, you should never perform comparisons between the results of floating point computations using == or !=. Use abs(number1 - number2) < epsilon // ==
abs(number1 - number2) >= epsilon // !=
instead, where epsilon is a small positive constant.
A graph might help explain why you are not getting the result you expected.
(source: wolfram.com)
http://mathworld.wolfram.com/Tangent.html
That shows the graph of Tan, but if you imagine reading off a value of x for a given y, (e.g. y = 0) then depending on which "strand" of Tan you read, you will get a different answer (-pi, 0, pi...). That's the point about Arctan(x) having more than one solution.
If arctan was restricted to only one of those strands, e.g. -pi/2 < x < pi/2 then Arctan(tan(x)) will return x providing you have accounted for floating point errors.
EDIT: However, according to http://msdn.microsoft.com/en-us/library/system.math.atan.aspx, the atan method already returns -pi/2 < x < pi/2 or NaN if your input is undefined. So the problem must soley be down to floating point rounding.
EDIT (F.R.): Added figure
I dont know any C#, but maths says that tan is not invertable, only in a small intervall.
e.g. tan(pi) = 0 and tan(0) = 0. When asking for atan(0) it could be 0 or pi (or every multiple of pi), so the result is in the range from -pi/2 .. pi/2.
Even if you start with an x in the invertable range i doesnt has to work, because of rounding errors with the floating points (it has not unlimmited precision).
tan-1(tan(x)) == x for all x in (-PI/2, PI/2).
Because the tangent function is periodic we need to normalize input angle. Math.Atan returns an angle, θ, measured in radians, such that -π/2 ≤ θ ≤ π/2, so it makes sense to normalize to that range (since it obviously won't anything within that range anyway):
double normalizedAngle = (angle + Math.PI / 2) % Math.PI - Math.PI / 2;
Doubles should be compared with some error margin. But in fact for this case Double.Epsilon is too small and "If you create a custom algorithm that determines whether two floating-point numbers can be considered equal, you must use a value that is greater than the Epsilon constant to establish the acceptable absolute margin of difference for the two values to be considered equal. (Typically, that margin of difference is many times greater than Epsilon.)" For instance, Math.Atan(Math.Tan(-0.49999632679501449)) + 0.49999632679501449 will be greater than Double.Epsilon for 1.1235582092889474E+307 times.
It might be helpful if you posted what you are trying to accomplish. I have recollections of discovering trig functions that handled the issue if what quadrant the inputs were in for me when I tried playing with angles, for example.
In general, when you are dealing with floating point numbers, you are dealing with approximations. There are numbers that cannot be represented exactly, and the tan and arctan operations are themselves only approximate.
If you want to compare floating point numbers, you need to ask if they are nearly equal, or equivalently, if the difference is less than some small value, and think carefully what you are doing.
Here is are some FAQS (for c++, but the idea is the same), that talk a bit about some of the oddities of floating point numbers:
FAQ 29.16
FAQ 29.17
FAQ 29.18
Edit: Looking at the other answers, I realise that the main problem is probably that tan isn't invertible, but the approximation issue is worth considering too, whenever you test floating point numbers for equality.
Looking at the .net documentation for Math.Atan, atan produces a value between -π/2 and ≤ π/2, which doesn't include 10. That I think is the usual range for arctan.
double d = Math.Atan(1) * (180 / Math.PI);
so d will be 45 in degrees