How is Math.Pow() implemented in .NET Framework? - c#

I was looking for an efficient approach for calculating ab (say a = 2 and b = 50). To start things up, I decided to take a look at the implementation of Math.Pow() function. But in .NET Reflector, all I found was this:
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern double Pow(double x, double y);
What are some of the resources wherein I can see as what's going on inside when I call Math.Pow() function?

MethodImplOptions.InternalCall
That means that the method is actually implemented in the CLR, written in C++. The just-in-time compiler consults a table with internally implemented methods and compiles the call to the C++ function directly.
Having a look at the code requires the source code for the CLR. You can get that from the SSCLI20 distribution. It was written around the .NET 2.0 time frame, I've found the low-level implementations, like Math.Pow() to be still largely accurate for later versions of the CLR.
The lookup table is located in clr/src/vm/ecall.cpp. The section that's relevant to Math.Pow() looks like this:
FCFuncStart(gMathFuncs)
FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMDouble::AbsFlt, CORINFO_INTRINSIC_Abs)
FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::AbsDbl, CORINFO_INTRINSIC_Abs)
FCFuncElement("Exp", COMDouble::Exp)
FCFuncElement("Pow", COMDouble::Pow)
// etc..
FCFuncEnd()
Searching for "COMDouble" takes you to clr/src/classlibnative/float/comfloat.cpp. I'll spare you the code, just have a look for yourself. It basically checks for corner cases, then calls the CRT's version of pow().
The only other implementation detail that's interesting is the FCIntrinsic macro in the table. That's a hint that the jitter may implement the function as an intrinsic. In other words, substitute the function call with a floating point machine code instruction. Which is not the case for Pow(), there is no FPU instruction for it. But certainly for the other simple operations. Notable is that this can make floating point math in C# substantially faster than the same code in C++, check this answer for the reason why.
By the way, the source code for the CRT is also available if you have the full version of Visual Studio vc/crt/src directory. You'll hit the wall on pow() though, Microsoft purchased that code from Intel. Doing a better job than the Intel engineers is unlikely. Although my high-school book's identity was twice as fast when I tried it:
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
But not a true substitute because it accumulates error from 3 floating point operations and doesn't deal with the weirdo domain problems that Pow() has. Like 0^0 and -Infinity raised to any power.

Hans Passant's answer is great, but I would like to add that if b is an integer, then a^b can be computed very efficiently with binary decomposition. Here's a modified version from Henry Warren's Hacker's Delight:
public static int iexp(int a, uint b) {
int y = 1;
while(true) {
if ((b & 1) != 0) y = a*y;
b = b >> 1;
if (b == 0) return y;
a *= a;
}
}
He notes that this operation is optimal (does the minimum number of arithmetic or logical operations) for all b < 15. Also there is no known solution to the general problem of finding an optimal sequence of factors to compute a^b for any b other than an extensive search. It's an NP-Hard problem. So basically that means that the binary decomposition is as good as it gets.

If freely available C version of pow is any indication, it does not look like anything you would expect. It would not be of much help to you to find the .NET version, because the problem that you are solving (i.e. the one with integers) is orders of magnitudes simpler, and can be solved in a few lines of C# code with the exponentiation by squaring algorithm.

Going through the answers, learned a lot about behind-the-scene calculations:
I've tried some workarounds on a coding platform which has an extensive test coverage cases, and found a very effective way doing it(Solution 3):
public double MyPow(double x, int n) {
double res = 1;
/* Solution 1: iterative : TLE(Time Limit Exceeded)
double res = 1;
var len = n > 0 ? n : -n;
for(var i = 0; i < len; ++i)
res *= x;
return n > 0 ? res : 1 / res;
*/
/* Solution 2: recursive => stackoverflow exception
if(x == 0) return n > 0 ? 0 : 1 / x;
if(n == 1) return x;
return n > 0 ? x * MyPow(x, n - 1) : (1/x) * MyPow(1/x, -n);
*/
//Solution 3:
if (n == 0) return 1;
var half = MyPow(x, n / 2);
if (n % 2 == 0)
return half * half;
else if (n > 0)
return half * half * x;
else
return half * half / x;
/* Solution 4: bitwise=> TLE(Time Limit Exceeded)
var b = n > 0 ? n : -n;
while(true) {
if ((b & 1) != 0)
res *= x;
b = b >> 1;
if (b == 0) break;
x *= x;
}
return n > 0 ? res : 1 / res;
*/
}

Answer that is accepted on Leetcode:
public class Solution {
public double MyPow(double x, int n) {
if(n==0) return 1;
long abs = Math.Abs((long)n);
var result = pow(x, abs);
return n > 0 ? result : 1/result;
}
double pow(double x, long n){
if(n == 1) return x;
var result = pow(x, n/2);
result = result * result * (n%2 == 1? x : 1);
return result;
}
}

Related

Floored integer division

Is there an easy, efficient and correct (i.e. not involving conversions to/from double) way to do floored integer division (like e.g. Python offers) in C#.
In other words, an efficient version of the following, that does not suffer from long/double conversion losses.
(long)(Math.Floor((double) a / b))
or does one have to implement it oneself, like e.g.
static long FlooredIntDiv(long a, long b)
{
if (a < 0)
{
if (b > 0)
return (a - b + 1) / b;
// if (a == long.MinValue && b == -1) // see *) below
// throw new OverflowException();
}
else if (a > 0)
{
if (b < 0)
return (a - b - 1) / b;
}
return a / b;
}
*) Although the C# 4 spec of the Division operator leaves it open whether OverflowException is raised inside unchecked, in reality it does throw (on my system) and the Visual Studio .NET 2003 version even mandated it throw:
If the left operand is the smallest representable int or long value and the right operand is –1, [..] System.OverflowException is always thrown in this situation, regardless of whether the operation occurs in a checked or an unchecked context.
Edit
The crossed out statements about checked and unchecked are all nice and well, but checked is in fact only a compile time concept, so whether my function should wrap around or throw is up to me anyway, regardless of whether code calling the function is inside checked or not.
You can try this:
if (((a < 0) ^ (b < 0)) && (a % b != 0))
{
return (a/b - 1);
}
else
{
return (a/b);
}
Edit (after some discussions in comments below):
Without using if-else, I would go like this:
return (a/b - Convert.ToInt32(((a < 0) ^ (b < 0)) && (a % b != 0)));
Note: Convert.ToIn32(bool value) also needs a jump, see implemention of the method:
return value? Boolean.True: Boolean.False;
Theoretically, it is not possible to calculate the division for a = long.MinValue and b = -1L, since the expected result is a/b = abs(long.MinValue) = long.MaxValue + 1 > long.MaxValue. (Range of long is –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.)
The way it works in any sane programming language (one that follows our normal order of operations) is that -1.0/3.0 is equivalent to -(1.0/3.0) which is -0.3333.... So if you want that converted to an int, it's really the cast/floor operator you need to think about, not the division. As such, if you want this behavior, you must use (int)Math.Floor(a/b), or custom code.
You don't need to implement this yourself, the Math class provides a builtin method for doing Euclidean division: Math.DivRem()
The only downside is that you have to provide an assignable variable for the remainder:
long remainder;
long quotient = Math.DivRem(a, b, out remainder);

Calculating Lucas Sequences efficiently

I'm implementing the p+1 factorization algorithm. For that I need to calculate elements of the lucas sequence which is defined by:
(1) x_0 = 1, x_1 = a
(2) x_n+l = 2 * a * x_n - x_n-l
I implemented it (C#) recursively but it is inefficient for bigger indexes.
static BigInteger Lucas(BigInteger a, BigInteger Q, BigInteger N)
{
if (Q == 0)
return 1;
if (Q == 1)
return a;
else
return (2 * a * Lucas(a, Q - 1, N) - Lucas(a, Q - 2, N)) % N;
}
I also know
(3) x_2n = 2 * (x_n)^2 - 1
(4) x_2n+1 = 2 * x_n+1 * x_n - a
(5) x_k(n+1) = 2 * x_k * x_kn - x_k(n-1)
(3) and (4) should help to calculate bigger Qs. But I'm unsure how.
Somehow with the binary form of Q I think.
Any help is appreciated.
Here one can see how to find Nth Fibbonaci number using matrix powering with matrix
n
(1 1)
(1 0)
You may exploit this approach to calculate Lucas numbers, using matrix (for your case x_n+l = 2 * a * x_n - x_n-l)
n
(2a -1)
(1 0)
Note that Nth power of matrix could be found with log(N) matrix multiplications by means of exponentiation by squaring
(3) x_2n = 2 * (x_n)^2 - 1
(4) x_2n+1 = 2 * x_n+1 * x_n - a
Whenever you see 2n, you should think "that probably indicates an even number", and similarly 2n+1 likely means "that's an odd number".
You can modify the x indices so you have n on the left (as to make it easier to understand how this corresponds to recursive function calls), just be careful regarding rounding.
3) 2n n
=> n n/2
4) it is easy to see that if x = 2n+1, then n = floor(x/2)
and similarly n+1 = ceil(x/2)
So, for #3, we have: (in pseudo-code)
if Q is even
return 2 * (the function call with Q/2) - 1
And for #4:
else // following from above if
return 2 * (the function call with floor(Q/2))
* (the function call with ceil(Q/2)) - a
And then we can also incorporate a bit of memoization to prevent calculating the return value for the same parameters multiple times:
Keep a map of Q value to return value.
At the beginning of the function, check if Q's value exists in the map. If so, return the corresponding return value.
When returning, add Q's value and the return value to the map.
The n-th Lucas number has the value:
Exponentiation by squaring can be used to evaluate the function. For example, if n=1000000000, then n = 1000 * 1000^2 = 10 * 10^2 * 1000^2 = 10 * 10^2 * (10 * 10^2 )^2. By simplifying in this way you can greatly reduce the number of calculations.
You can get some improvements (just a factor of a million...) without resorting to really fancy math.
First let's make the data flow a little more explicit:
static BigInteger Lucas(BigInteger a, BigInteger Q, BigInteger N)
{
if (Q == 0)
{
return 1;
}
else if (Q == 1)
{
return a;
}
else
{
BigInteger q_1 = Lucas(a, Q - 1, N);
BigInteger q_2 = Lucas(a, Q - 2, N);
return (2 * a * q_1 - q_2) % N;
}
}
Unsurprisingly, this doesn't really change the performance.
However, it does make it clear that we only need two previous values to compute the next value. This lets us turn the function upside down into an iterative version:
static BigInteger IterativeLucas(BigInteger a, BigInteger Q, BigInteger N)
{
BigInteger[] acc = new BigInteger[2];
Action<BigInteger> push = (el) => {
acc[1] = acc[0];
acc[0] = el;
};
for (BigInteger i = 0; i <= Q; i++)
{
if (i == 0)
{
push(1);
}
else if (i == 1)
{
push(a);
}
else
{
BigInteger q_1 = acc[0];
BigInteger q_2 = acc[1];
push((2 * a * q_1 - q_2) % N);
}
}
return acc[0];
}
There might be a clearer way to write this, but it works. It's also much faster. It's so much faster it's kind of impractical to measure. On my system, Lucas(4000000, 47, 4000000) took about 30 minutes, and IterativeLucas(4000000, 47, 4000000) took about 2 milliseconds. I wanted to compare 48, but I didn't have the patience.
You can squeeze a little more out (maybe a factor of two?) using these properties of modular arithmetic:
(a + b) % n = (a%n + b%n) % n
(a * b) % n = ((a%n) * (b%n)) % n
If you apply these, you'll find that a%N occurs a few times so you can win by precomputing it once before the loop. This is particularly helpful when a is a lot bigger than N; I'm not sure if that happens in your application.
There are probably some clever mathematical techniques that would blow this solution out of the water, but I think it's interesting that such an improvement can be achieved just by shuffling a little code around.

Fermat primality test

I have tried to write a code for Fermat primality test, but apparently failed.
So if I understood well: if p is prime then ((a^p)-a)%p=0 where p%a!=0.
My code seems to be OK, therefore most likely I misunderstood the basics. What am I missing here?
private bool IsPrime(int candidate)
{
//checking if candidate = 0 || 1 || 2
int a = candidate + 1; //candidate can't be divisor of candidate+1
if ((Math.Pow(a, candidate) - a) % candidate == 0) return true;
return false;
}
Reading the wikipedia article on the Fermat primality test, You must choose an a that is less than the candidate you are testing, not more.
Furthermore, as MattW commented, testing only a single a won't give you a conclusive answer as to whether the candidate is prime. You must test many possible as before you can decide that a number is probably prime. And even then, some numbers may appear to be prime but actually be composite.
Your basic algorithm is correct, though you will have to use a larger data type than int if you want to do this for non-trivial numbers.
You should not implement the modular exponentiation in the way that you did, because the intermediate result is huge. Here is the square-and-multiply algorithm for modular exponentiation:
function powerMod(b, e, m)
x := 1
while e > 0
if e%2 == 1
x, e := (x*b)%m, e-1
else b, e := (b*b)%m, e//2
return x
As an example, 437^13 (mod 1741) = 819. If you use the algorithm shown above, no intermediate result will be greater than 1740 * 1740 = 3027600. But if you perform the exponentiation first, the intermediate result of 437^13 is 21196232792890476235164446315006597, which you probably want to avoid.
Even with all of that, the Fermat test is imperfect. There are some composite numbers, the Carmichael numbers, that will always report prime no matter what witness you choose. Look for the Miller-Rabin test if you want something that will work better. I modestly recommend this essay on Programming with Prime Numbers at my blog.
You are dealing with very large numbers, and trying to store them in doubles, which is only 64 bits.
The double will do the best it can to hold your number, but you are going to loose some accuracy.
An alternative approach:
Remember that the mod operator can be applied multiple times, and still give the same result.
So, to avoid getting massive numbers you could apply the mod operator during the calculation of your power.
Something like:
private bool IsPrime(int candidate)
{
//checking if candidate = 0 || 1 || 2
int a = candidate - 1; //candidate can't be divisor of candidate - 1
int result = 1;
for(int i = 0; i < candidate; i++)
{
result = result * a;
//Notice that without the following line,
//this method is essentially the same as your own.
//All this line does is keeps the numbers small and manageable.
result = result % candidate;
}
result -= a;
return result == 0;
}

Fast algorithm for pandigital check

I'm working on a project for which I need a very fast algorithm for checking whether a supplied number is pandigital. Though the logic seems sound, I'm not particularly happy with performance of the methods described below.
I can check up to one million 9-digit numbers in about 520ms, 600ms and 1600ms respectively. I'm working on a low-latency application and in production I'll have a dataset of about 9 or 9.5 billion 7- to 9-digit numbers that I'll need to check.
I have three candidiates right now (well, really two) that use the following logic:
Method 1: I take an input N, split into into a byte array of its constituent digits, sort it using an Array.Sort function and iterate over the array using a for loop checking for element vs counter consistency:
byte[] Digits = SplitDigits(N);
int len = NumberLength(N);
Array.Sort(Digits);
for (int i = 0; i <= len - 1; i++)
{
if (i + 1 != Digits[i])
return false;
}
Method 2: This method is based on a bit of dubious logic, but I split the input N into a byte array of constituent digits and then make the following test:
if (N * (N + 1) * 0.5 == DigitSum(N) && Factorial(len) == DigitProduct(N))
return true;
Method 3: I dislike this method, so not a real candidate but I cast the int to a string and then use String.Contains to determine if the required string is pandigital.
The second and third method have fairly stable runtimes, though the first method bounces around a lot - it can go as high as 620ms at times.
So ideally I really like to reduce the runtime for the million 9-digit mark to under 10ms. Any thoughts?
I'm running this on a Pentium 6100 laptop at 2GHz.
PS - is the mathematical logic of the second method sound?
Method 1
Pre-compute a sorted list of the 362880 9-digit pandigital numbers. This will take only a few milliseconds. Then for each request, first check if the number is divisible by 9: It must be to be pandigital. If it is, then use a binary search to check if it is in your pre-computed list.
Method 2
Again, check if the number is divisible by 9. Then use a bit vector to track the presence of digits. Also use modular multiplication to replace the division by a multiplication.
static bool IsPandigital(int n)
{
if (n != 9 * (int)((0x1c71c71dL * n) >> 32))
return false;
int flags = 0;
while (n > 0) {
int q = (int)((0x1999999aL * n) >> 32);
flags |= 1 << (n - q * 10);
n = q;
}
return flags == 0x3fe;
}
Method 1 comes in at 15ms/1M. Method 2 comes in at 5.5ms/1M on my machine. This is C# compiled to x64 on an i7 950.
just a thought: (after the definitition of pandigital from wikipedia)
int n = 1234567890;
int Flags = 0;
int Base = 10;
while(n != 0)
{
Flags |= 1<<(n % Base); n /= Base;
}
bool bPanDigital = Flags == ((1 << Base) - 1);

C# function to find the delta of two numbers [duplicate]

This question already has answers here:
Difference between 2 numbers
(6 answers)
Closed 5 years ago.
I just wanted to know if there's anything built into the .net framework where I can easily return the delta between two numbers? I wrote code that does this but it sounds like something that should be in the framework already.
delta = Math.Abs(a - b);
I'm under the impression that "delta" is the difference between two numbers.
Until you tell me differently, I think what you want is:
delta = Math.Abs(a - b);
public static int Delta(int a, int b)
{
int delta = 0;
if (a == b)
{
return 0;
}
else if (a < b)
{
while (a < b)
{
a++;
delta++;
}
return delta;
}
else
{
while (b < a)
{
b++;
delta++;
}
return delta;
}
}
:p
Oh boy, I hope no (future) employer comes across this and stops reading in disgust before he reaches the end of this post..
The Linq version (requires CLR 4.0).
(cracks fingers, clears throat)
var delta = (from t in Enumerable.Range(a, a).Zip(Enumerable.Range(b, b))
select Math.Abs(t.Item1 - t.Item2))
.First();
Isn't that what the minus operator does? :p
public static int Delta(int a, int b)
{
return a > 0? Delta(a-1, b-1) : a < 0 ? Delta(a+1, b+1) : b > 0 ? b : -b;
}
I think that's even better than #JulianR Delta implementation :-p
Edit: I didn't realize that this was already suggested by #Robert Harvey, credit to him ;-)
What is the delta of two numbers?
Delta has a certain meaning in set-theory and infinitesimal calculus, but this doesn't refer to numbers!
If you want to calculate the difference between two numbers a and b, you write |a - b| which is Math.Abs(a - b) in C#.
I decided to revise JulianR's funny answer above.
The code is shorter, but perhaps more tricky:
public static int Delta(int a, int b)
{
int delta = 0;
while (a < b)
{
++a;
++delta;
}
while (b < a)
{
++b;
++delta;
}
return delta;
}
(for the humor-impaired.... this is no more serious than the bizarre question that started the thread)
(r1+r2)/2
Avarage between two numbers.

Categories