Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 09-20-2007
TriKri
Hi, is there a possibility to use advanced math functions during the pre-compiling? For example, I have defined D_TYPE, currently to unsigned int, D_BITS to (sizeof(D_TYPE)*8), then I want to have a macro named BASE, which is the largest potens of 10, below 2^(D_BITS -1) - 1 (where ^ is the power function), or (the maximum value D_TYPE can accept)/2. So, using mathematical functions it would be something like 10^(floor(log(D_TYPE_MAX/2))). And the floor(log(D_TYPE_MAX/2)) part of the macro definition could be another macro called B_DIGITS, so that BASE is defined as 10^B_DIGITS (^ is not xor this time either).
• 09-20-2007
brewbuck
Quote:

Originally Posted by TriKri
Hi, is there a possibility to use advanced math functions during the pre-compiling? For example, I have defined D_TYPE, currently to unsigned int, D_BITS to (sizeof(D_TYPE)*8), then I want to have a macro named BASE, which is the largest potens of 10, below 2^(D_BITS -1) - 1 (where ^ is the power function), or (the maximum value D_TYPE can accept)/2. So, using mathematical functions it would be something like 10^(floor(log(D_TYPE_MAX/2))). And the floor(log(D_TYPE_MAX/2)) part of the macro definition could be another macro called B_DIGITS, so that BASE is defined as 10^B_DIGITS (^ is not xor this time either).

The Boost integer library might be handy.
• 09-20-2007
TriKri
But how can I use a library in precompiling? :P
• 09-20-2007
Codeplug
<boost/integer/static_log2.hpp> is an example of how to compute floor(log2(N)) at compile time. There may be other tools in boost to help, I'm not sure.

Here's a good intro to template meta-programs - check out the links at the top as well.

http://ubiety.uwaterloo.ca/~tveldhui.../meta-art.html

gg
• 09-20-2007
TriKri
Thanks, I'm gonna check that out!
• 09-20-2007
Codeplug
I do enjoy a challenge :)
Here's code that will essentially calculate floor(log10(N)) at compile time.
Code:

```#include<iostream> using namespace std; // compile time pow() template<int X, int Y> struct ctime_pow {     enum {result = X * ctime_pow<X, Y-1>::result}; }; // specialization for pow(X, 0) to stop recursion template<int X> struct ctime_pow<X, 0> {     enum {result = 1}; }; // recusively calculate X^Potens where X^Potens <= MAX template<int X, int Potens, int MAX, bool bStop> struct greatest_pow_imp {     enum {result = greatest_pow_imp<X,                                     Potens + 1,                                     MAX,                                     (ctime_pow<X, Potens + 1>::result > MAX)>::result}; }; // specialization where bStop is true, "choose" Potens - 1 template<int X, int Potens, int MAX> struct greatest_pow_imp<X, Potens, MAX, true> {     enum {result = Potens - 1}; }; // calculate greatest power of X that is <= MAX template<int X, int MAX> struct greatest_pow //less than or equal to MAX {     enum {result = greatest_pow_imp<X, 0, MAX, false>::result}; }; #define TEST(X, MAX) \     cout << "greatest_pow<" #X ", " #MAX ">::result = " \         << greatest_pow<X, MAX>::result << endl int main() {     TEST(10, 0);     TEST(10, 1);     TEST(10, 9);     TEST(10, 10);     TEST(10, 99);     TEST(10, 100);     TEST(10, 999);     TEST(10, 1000);     return 0; }//main```
gg
• 09-20-2007
brewbuck
Quote:

Originally Posted by Codeplug
I do enjoy a challenge :)
Here's code that will essentially calculate floor(log10(N)) at compile time.

You seem to have caught on to that awfully quick. Welcome to the metaprogrammer's guild!

EDIT: Haha, nevermind. I had you confused with the OP :)
• 09-21-2007
TriKri
Nice Codeplug!

So the < ... > is really just for making multiple definitions from one code snippet in compile time, whether it is unique intereger numbers or type names laying inside it? That can be quite usefull. Templates, isn't it?
• 09-25-2007
TriKri
And if you would like to make
Code:

```template<int X, int Y> struct ctime_pow {     enum {result = X * ctime_pow<X, Y-1>::result}; };```
valid for all types of X, not only ints, how do you write then?
• 09-25-2007
Daved
You can't, it has to be an integral type. I think you can use short, long or char (or probably even bool) but you can't use a floating type for this kind of template metaprogramming.
• 09-25-2007
TriKri
Quote:

Originally Posted by Daved
You can't, it has to be an integral type. I think you can use short, long or char (or probably even bool) but you can't use a floating type for this kind of template metaprogramming.

I didn't have any specific type in mind, I just thought maybe we can generalize this to cover all possible types that can be used in preprocessing. Or do you have to choose?

I have tried
• template<T X, int Y> //T not defined
• template<class T, T X, int Y> //Also produces an error
• template<class T X, int Y> //Wrong syntax
• template<class T, int Y> POW<T X, int Y>//Wrong syntax again
etc.

Is there any way to do this?
• 09-25-2007
Daved
I don't think so, but why would you want to? If you use long that's probably the best you can do, because any number that fits for any of the other types would fit for long as well.
• 09-25-2007
TriKri
Quote:

Originally Posted by Daved
I don't think so, but why would you want to? If you use long that's probably the best you can do, because any number that fits for any of the other types would fit for long as well.

Why does it have to be an integral type, I thought you could use any type you wanted when writing templates? I'd like to make it work for floats and doubles as well... :/
• 09-25-2007
Daved
You can do different things with templates. You can do something where the code depends on the type like a vector<T> or something like this:
Code:

```template <typename T> void outputData(std::ostream& out, T data) {   out << data; };```
Those things don't work on any type, they only work on types that don't cause compile errors when you replace T with that type, but that's what you're thinking of.

I different way to use templates is to use an integer value instead of a type. An example of this is Codeplug's code. The point of it is not to be generic code that can work on different types, the point is to take advantage of the compiler and the template system to do work at the compilation stage and avoid doing that work at runtime.
• 09-25-2007
TriKri
Hmm, I se. Maybe I'll use it at the time and IFF I need the same code some other time but with some other type I'll rewrite it for that specific type ... but thank you. It can be good to know! ;)
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last