Getting more than one implicit conversion

C

Cory Nelson

In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?
 
D

Daniel T.

"Cory Nelson said:
In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?

Make one explicit. unit512 = uint128( 0 );
 
G

Greg

Cory said:
In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?

if this is the only use for the conversion, I would point out that
there no need to initialize a uint512 to 0 since the default
constructor for a uint512 initializes itself to 0.

Greg
 
K

Kai-Uwe Bux

Cory said:
In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?

When I did something like that, I just added a constructor from unsigned
long everywhere. Here is what I did:

template < unsigned short N >
class u_int {
private:

u_int<N-1> h;
u_int<N-1> l;

public:

static
const
unsigned long bit_length = 2*u_int<N-1>::bit_length;

inline
u_int ( void )
// : h ( u_int<N-1>() ), l ( u_int<N-1>() )
{}

inline
u_int ( unsigned long small ) :
h ( u_int<N-1>::zero ),
l ( small )
{}

inline
u_int ( const u_int & other ) :
h ( other.h ),
l ( other.l )
{}

inline
u_int ( const u_int<N-1> & _h,
const u_int<N-1> & _l ) :
h ( _h ),
l ( _l )
{}

inline
~u_int ( void )
{};

inline
void clear ( void ) {
h.clear();
l.clear();
}

// ...

};

As you can guess, the template takes care of the code used to double the
length of an integer type. Finally, you add a specialization for u_int<5>
or u_int<6> that uses a built in type of length 32 or 64.


Best

Kai-Uwe Bux
 
G

Greg

Cory said:
In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?

Declare a helper subclass to perform the conversion:

struct uint512FromUnsignedLong : public uint512
{
uint512FromUnsignedLong(unsigned long ul)
: uint512( uint256( uint128(ul)))
{
}
};

Usage:

int main()
{
uint512FromUnsignedLong bigInt = 42;

uint512 bigInt2;

bigInt2 = uint512FromUnsignedLong(12);

Greg
 
G

Greg

Cory said:
In the class here: http://dev.int64.org/snips/bigint.hpp

I want to do uint512 = 0;

large_integer has a constuctor taking the lo-word (a uint256 in this
case), so this currently goes from long long -> uint128 -> uint256.

That means one too many implicit conversions - I'm trying to find a way
around that. Any suggestions?

Declare a helper subclass with the appropriate converting constructor:

struct uint512FromUnsignedLong : public uint512
{
uint512FromUnsignedLong(unsigned long ul)
: uint512( uint256( uint128(ul)))
{
}
};


Here are two examples of the helper subclass in use:

int main()
{
uint512FromUnsignedLong bigInt = 42;

// now use bigInt as an uint512 per usual
...

// can also assign a ulong to an uint512:

uint512 bigInt2;

bigInt2 = uint512FromUnsignedLong(12);

Greg
 
C

Cory Nelson

Well, I was hoping for a way to do this without specializing, so I can
also reuse the code for uint1024 and as high as I want. I figured some
form of recursive MPL might be able to accomplish that but am not sure
where to start.
 
G

Greg

Cory said:
Well, I was hoping for a way to do this without specializing, so I can
also reuse the code for uint1024 and as high as I want. I figured some
form of recursive MPL might be able to accomplish that but am not sure
where to start.

A recursive template function would offer a more generalized solution:

template <class T>
T new_(unsigned long n)
{
return T( new_<typename T::base_type>(n));
}

template <>
uint128 new_<uint128>(unsigned long n)
{
return uint128(n);
}

typedef large_integer<uint512> uint1024;

int main()
{
uint512 num1 = new_<uint512>(34);
uint1024 num2 = new_<uint1024>(12);
...
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top