Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choose smallest integer type based on a float

I'm trying to write a class which includes a variable whose type would be chosen to be the smallest possible able to contain a value.

What I mean is:

class foo {
 "int type here" a;
}

I came across Automatically pick a variable type big enough to hold a specified number. Due to difficulties using the boost library, I went ahead and used the template suggestions.

That turns the code into:

template<unsigned long long T>
class foo {
 SelectInteger<T>::type a;
}

However, my problem arises from the fact that the variable's size is a result of multiplying a floating point variable and integer. Therefore, what I would like to be able to do is:

template<unsigned long long T, double E>
class foo {
 SelectInteger<T*E>::type a;
}

But since templates don't work with floating point variables (see here), I can't pass E in a template. Is there some other way I can pass a variable (which should be available during compilation) to the class?

like image 230
I. El Avatar asked Jun 16 '17 10:06

I. El


People also ask

Is 1.0 integer or float?

For example, 1 is an integer literal, while 1.0 is a floating-point literal; their binary in-memory representations as objects are numeric primitives.

Is 3.0 A float number?

With integers and floating-point numbers, it is important to keep in mind that 3 ≠ 3.0, as 3 refers to an integer while 3.0 refers to a float.

Can Float take integer values?

Yes, an integral value can be added to a float value. The basic math operations ( + , - , * , / ), when given an operand of type float and int , the int is converted to float first.

Is size of int and float same?

An integer is just a number... It's range depends on the number of bits (different for a signed or unsigned integer). A floating point number is a whole different thing.


1 Answers

What about using a constexpr function ?

I mean... something as follows

template <unsigned long long>
struct SelectInteger
 { using type = int; };

template <>
struct SelectInteger<0U>
 { using type = short; };

constexpr unsigned long long getSize (unsigned long long ull, double d)
 { return ull*d; }

template <unsigned long long T>
struct foo
 { typename SelectInteger<T>::type a; };

int main()
 {
   static_assert( std::is_same<short,
                     decltype(foo<getSize(1ULL, 0.0)>::a)>::value, "!");
   static_assert( std::is_same<int,
                     decltype(foo<getSize(1ULL, 1.0)>::a)>::value, "!!");
 }
like image 143
max66 Avatar answered Oct 03 '22 09:10

max66