Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I compute pow(10,x) at compile-time in c?

Is it possible to compute pow(10,x) at compile time?

I've got a processor without floating point support and slow integer division. I'm trying to perform as many calculations as possible at compile time. I can dramatically speed up one particular function if I pass both x and C/pow(10,x) as arguments (x and C are always constant integers, but they are different constants for each call). I'm wondering if I can make these function calls less error prone by introducing a macro which does the 1/pow(10,x) automatically, instead of forcing the programmer to calculate it?

Is there a pre-processor trick? Can I force the compiler optimize out the library call?

like image 252
AShelly Avatar asked Jun 30 '09 21:06

AShelly


People also ask

What is the time complexity of POW?

Time Complexity: O(N) because pow(x,n) is called recursively for each number from 1 to n. Space Complexity: O(1) No extra space has been used.

Is there POW function in C?

Power Function in C/C++ Given two numbers base and exponent, pow() function finds x raised to the power of y i.e. xy. Basically in C exponent value is calculated using the pow() function. pow() is function to get the power of a number, but we have to use #include<math.

How do you write a power of 10 in C++?

Because it can be hard to type or display exponents in C++, we use the letter 'e' (or sometimes 'E') to represent the “times 10 to the power of” part of the equation. For example, 1.2 x 10⁴ would be written as 1.2e4 , and 5.9736 x 10²⁴ would be written as 5.9736e24 .

How do you calculate POW?

The most basic way to calculate the nth power of a number is to multiply that number exactly n-times. In this case, we could just find the inverse of its positive power i.e. pow(2,-3) = 1/(2^3).


3 Answers

Actually, by exploiting the C preprocessor, you can get it to compute C pow(10, x) for any real C and integral x. Observe that, as @quinmars noted, C allows you to use scientific syntax to express numerical constants:

#define myexp 1.602E-19   // == 1.602 * pow(10, -19)

to be used for constants. With this in mind, and a bit of cleverness, we can construct a preprocessor macro that takes C and x and combine them into an exponentiation token:

#define EXP2(a, b) a ## b
#define EXP(a, b) EXP2(a ## e,b)
#define CONSTPOW(C,x) EXP(C, x)

This can now be used as a constant numerical value:

const int myint = CONSTPOW(3, 4); // == 30000
const double myfloat = CONSTPOW(M_PI, -2); // == 0.03141592653
like image 108
Jon Gjengset Avatar answered Oct 21 '22 19:10

Jon Gjengset


You can do it with Boost.Preprocessor:

http://www.boost.org/doc/libs/1_39_0/libs/preprocessor/doc/index.html

Code:

#include <boost/preprocessor/repeat.hpp>

#define _TIMES_10(z, n, data) * 10
#define POW_10(n) (1 BOOST_PP_REPEAT(n, _TIMES_10, _))

int test[4] = {POW_10(0), POW_10(1), POW_10(2), POW_10(3)};
like image 34
e.tadeu Avatar answered Oct 21 '22 19:10

e.tadeu


If you just need to use the value at compile time, use the scientific notation like 1e2 for pow(10, 2)

If you want to populate the values at compile time and then use them later at runtime then simply use a lookup table because there are only 23 different powers of 10 that are exactly representable in double precision

double POW10[] = {1., 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};

You can get larger powers of 10 at runtime from the above lookup table to quickly get the result without needing to multiply by 10 again and again, but the result is just a value close to a power of 10 like when you use 10eX with X > 22

double pow10(int x)
{
   if (x > 22)
      return POW10[22] * pow10(x - 22);
   else if (x >= 0)
      return POW10[x];
    else
        return 1/pow10(-x);
}

If negative exponents is not needed then the final branch can be removed.

You can also reduce the lookup table size further if memory is a constraint. For example by storing only even powers of 10 and multiply by 10 when the exponent is odd, the table size is now only a half.

like image 34
phuclv Avatar answered Oct 21 '22 18:10

phuclv