@ -1,11 +1,13 @@
@@ -1,11 +1,13 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ifndef BITCOIN_UINT256_H
# define BITCOIN_UINT256_H
# include <assert.h>
# include <stdexcept>
# include <stdint.h>
# include <stdio.h>
# include <string>
@ -19,17 +21,59 @@ inline signed char HexDigit(char c)
@@ -19,17 +21,59 @@ inline signed char HexDigit(char c)
return p_util_hexdigit [ ( unsigned char ) c ] ;
}
/** Base class without constructors for uint256 and uint160.
* This makes the compiler let you use it in a union .
*/
class uint_error : public std : : runtime_error {
public :
explicit uint_error ( const std : : string & str ) : std : : runtime_error ( str ) { }
} ;
/** Template base class for unsigned big integers. */
template < unsigned int BITS >
class base_uint
{
protected :
private :
enum { WIDTH = BITS / 32 } ;
uint32_t pn [ WIDTH ] ;
public :
base_uint ( )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
base_uint ( const base_uint & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
}
base_uint & operator = ( const base_uint & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
return * this ;
}
base_uint ( uint64_t b )
{
pn [ 0 ] = ( unsigned int ) b ;
pn [ 1 ] = ( unsigned int ) ( b > > 32 ) ;
for ( int i = 2 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
explicit base_uint ( const std : : string & str )
{
SetHex ( str ) ;
}
explicit base_uint ( const std : : vector < unsigned char > & vch )
{
if ( vch . size ( ) ! = sizeof ( pn ) )
throw uint_error ( " Converting vector of wrong size to base_uint " ) ;
memcpy ( pn , & vch [ 0 ] , sizeof ( pn ) ) ;
}
bool operator ! ( ) const
{
for ( int i = 0 ; i < WIDTH ; i + + )
@ -178,6 +222,57 @@ public:
@@ -178,6 +222,57 @@ public:
return * this ;
}
base_uint & operator * = ( uint32_t b32 )
{
uint64_t carry = 0 ;
for ( int i = 0 ; i < WIDTH ; i + + )
{
uint64_t n = carry + ( uint64_t ) b32 * pn [ i ] ;
pn [ i ] = n & 0xffffffff ;
carry = n > > 32 ;
}
return * this ;
}
base_uint & operator * = ( const base_uint & b )
{
base_uint a = * this ;
* this = 0 ;
for ( int j = 0 ; j < WIDTH ; j + + ) {
uint64_t carry = 0 ;
for ( int i = 0 ; i + j < WIDTH ; i + + ) {
uint64_t n = carry + pn [ i + j ] + ( uint64_t ) a . pn [ j ] * b . pn [ i ] ;
pn [ i + j ] = n & 0xffffffff ;
carry = n > > 32 ;
}
}
return * this ;
}
base_uint & operator / = ( const base_uint & b )
{
base_uint div = b ; // make a copy, so we can shift.
base_uint num = * this ; // make a copy, so we can subtract.
* this = 0 ; // the quotient.
int num_bits = num . bits ( ) ;
int div_bits = div . bits ( ) ;
if ( div_bits = = 0 )
throw uint_error ( " Division by zero " ) ;
if ( div_bits > num_bits ) // the result is certainly 0.
return * this ;
int shift = num_bits - div_bits ;
div < < = shift ; // shift so that div and nun align.
while ( shift > = 0 ) {
if ( num > = div ) {
num - = div ;
pn [ shift / 32 ] | = ( 1 < < ( shift & 31 ) ) ; // set a bit of the result.
}
div > > = 1 ; // shift back.
shift - - ;
}
// num now contains the remainder of the division.
return * this ;
}
base_uint & operator + + ( )
{
@ -213,86 +308,46 @@ public:
@@ -213,86 +308,46 @@ public:
return ret ;
}
friend inline bool operator < ( const base_uint & a , const base_uint & b )
{
for ( int i = base_uint : : WIDTH - 1 ; i > = 0 ; i - - )
{
if ( a . pn [ i ] < b . pn [ i ] )
return true ;
else if ( a . pn [ i ] > b . pn [ i ] )
return false ;
}
return false ;
}
friend inline bool operator < = ( const base_uint & a , const base_uint & b )
{
for ( int i = base_uint : : WIDTH - 1 ; i > = 0 ; i - - )
{
if ( a . pn [ i ] < b . pn [ i ] )
return true ;
else if ( a . pn [ i ] > b . pn [ i ] )
return false ;
int CompareTo ( const base_uint & b ) const {
for ( int i = base_uint : : WIDTH - 1 ; i > = 0 ; i - - ) {
if ( pn [ i ] < b . pn [ i ] )
return - 1 ;
if ( pn [ i ] > b . pn [ i ] )
return 1 ;
}
return true ;
return 0 ;
}
friend inline bool operator > ( const base_uint & a , const base_uint & b )
{
for ( int i = base_uint : : WIDTH - 1 ; i > = 0 ; i - - )
{
if ( a . pn [ i ] > b . pn [ i ] )
return true ;
else if ( a . pn [ i ] < b . pn [ i ] )
bool EqualTo ( uint64_t b ) const {
for ( int i = base_uint : : WIDTH - 1 ; i > = 2 ; i - - ) {
if ( pn [ i ] )
return false ;
}
return false ;
}
friend inline bool operator > = ( const base_uint & a , const base_uint & b )
{
for ( int i = base_uint : : WIDTH - 1 ; i > = 0 ; i - - )
{
if ( a . pn [ i ] > b . pn [ i ] )
return true ;
else if ( a . pn [ i ] < b . pn [ i ] )
return false ;
}
return true ;
}
friend inline bool operator = = ( const base_uint & a , const base_uint & b )
{
for ( int i = 0 ; i < base_uint : : WIDTH ; i + + )
if ( a . pn [ i ] ! = b . pn [ i ] )
return false ;
return true ;
}
friend inline bool operator = = ( const base_uint & a , uint64_t b )
{
if ( a . pn [ 0 ] ! = ( unsigned int ) b )
if ( pn [ 1 ] ! = ( b > > 32 ) )
return false ;
if ( a . pn [ 1 ] ! = ( unsigned int ) ( b > > 32 ) )
if ( pn [ 0 ] ! = ( b & 0xfffffffful ) )
return false ;
for ( int i = 2 ; i < base_uint : : WIDTH ; i + + )
if ( a . pn [ i ] ! = 0 )
return false ;
return true ;
}
friend inline bool operator ! = ( const base_uint & a , const base_uint & b )
{
return ( ! ( a = = b ) ) ;
}
friend inline bool operator ! = ( const base_uint & a , uint64_t b )
{
return ( ! ( a = = b ) ) ;
}
friend inline const base_uint operator + ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) + = b ; }
friend inline const base_uint operator - ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) - = b ; }
friend inline const base_uint operator * ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) * = b ; }
friend inline const base_uint operator / ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) / = b ; }
friend inline const base_uint operator | ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) | = b ; }
friend inline const base_uint operator & ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) & = b ; }
friend inline const base_uint operator ^ ( const base_uint & a , const base_uint & b ) { return base_uint ( a ) ^ = b ; }
friend inline const base_uint operator > > ( const base_uint & a , int shift ) { return base_uint ( a ) > > = shift ; }
friend inline const base_uint operator < < ( const base_uint & a , int shift ) { return base_uint ( a ) < < = shift ; }
friend inline const base_uint operator * ( const base_uint & a , uint32_t b ) { return base_uint ( a ) * = b ; }
friend inline bool operator = = ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) = = 0 ; }
friend inline bool operator ! = ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) ! = 0 ; }
friend inline bool operator > ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) > 0 ; }
friend inline bool operator < ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) < 0 ; }
friend inline bool operator > = ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) > = 0 ; }
friend inline bool operator < = ( const base_uint & a , const base_uint & b ) { return a . CompareTo ( b ) < = 0 ; }
friend inline bool operator = = ( const base_uint & a , uint64_t b ) { return a . EqualTo ( b ) ; }
friend inline bool operator ! = ( const base_uint & a , uint64_t b ) { return ! a . EqualTo ( b ) ; }
std : : string GetHex ( ) const
{
@ -367,269 +422,134 @@ public:
@@ -367,269 +422,134 @@ public:
return sizeof ( pn ) ;
}
// Returns the position of the highest bit set plus one, or zero if the
// value is zero.
unsigned int bits ( ) const
{
for ( int pos = WIDTH - 1 ; pos > = 0 ; pos - - ) {
if ( pn [ pos ] ) {
for ( int bits = 31 ; bits > 0 ; bits - - ) {
if ( pn [ pos ] & 1 < < bits )
return 32 * pos + bits + 1 ;
}
return 32 * pos + 1 ;
}
}
return 0 ;
}
uint64_t GetLow64 ( ) const
{
assert ( WIDTH > = 2 ) ;
return pn [ 0 ] | ( uint64_t ) pn [ 1 ] < < 32 ;
}
// unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
unsigned int GetSerializeSize ( int nType , int nVersion ) const
{
return sizeof ( pn ) ;
}
template < typename Stream >
// void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
void Serialize ( Stream & s , int nType , int nVersion ) const
{
s . write ( ( char * ) pn , sizeof ( pn ) ) ;
}
template < typename Stream >
// void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
void Unserialize ( Stream & s , int nType , int nVersion )
{
s . read ( ( char * ) pn , sizeof ( pn ) ) ;
}
friend class uint160 ;
friend class uint256 ;
} ;
typedef base_uint < 160 > base_uint160 ;
typedef base_uint < 256 > base_uint256 ;
//
// uint160 and uint256 could be implemented as templates, but to keep
// compile errors and debugging cleaner, they're copy and pasted.
//
//////////////////////////////////////////////////////////////////////////////
//
// uint160
//
/** 160-bit unsigned integer */
class uint160 : public base_uint160
{
/** 160-bit unsigned big integer. */
class uint160 : public base_uint < 160 > {
public :
typedef base_uint160 basetype ;
uint160 ( )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
uint160 ( const basetype & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
}
uint160 & operator = ( const basetype & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
return * this ;
}
uint160 ( uint64_t b )
{
pn [ 0 ] = ( unsigned int ) b ;
pn [ 1 ] = ( unsigned int ) ( b > > 32 ) ;
for ( int i = 2 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
uint160 & operator = ( uint64_t b )
{
pn [ 0 ] = ( unsigned int ) b ;
pn [ 1 ] = ( unsigned int ) ( b > > 32 ) ;
for ( int i = 2 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
return * this ;
}
explicit uint160 ( const std : : string & str )
{
SetHex ( str ) ;
}
explicit uint160 ( const std : : vector < unsigned char > & vch )
{
if ( vch . size ( ) = = sizeof ( pn ) )
memcpy ( pn , & vch [ 0 ] , sizeof ( pn ) ) ;
else
* this = 0 ;
}
uint160 ( ) { }
uint160 ( const base_uint < 160 > & b ) : base_uint < 160 > ( b ) { }
uint160 ( uint64_t b ) : base_uint < 160 > ( b ) { }
explicit uint160 ( const std : : string & str ) : base_uint < 160 > ( str ) { }
explicit uint160 ( const std : : vector < unsigned char > & vch ) : base_uint < 160 > ( vch ) { }
} ;
inline bool operator = = ( const uint160 & a , uint64_t b ) { return ( base_uint160 ) a = = b ; }
inline bool operator ! = ( const uint160 & a , uint64_t b ) { return ( base_uint160 ) a ! = b ; }
inline const uint160 operator < < ( const base_uint160 & a , unsigned int shift ) { return uint160 ( a ) < < = shift ; }
inline const uint160 operator > > ( const base_uint160 & a , unsigned int shift ) { return uint160 ( a ) > > = shift ; }
inline const uint160 operator < < ( const uint160 & a , unsigned int shift ) { return uint160 ( a ) < < = shift ; }
inline const uint160 operator > > ( const uint160 & a , unsigned int shift ) { return uint160 ( a ) > > = shift ; }
inline const uint160 operator ^ ( const base_uint160 & a , const base_uint160 & b ) { return uint160 ( a ) ^ = b ; }
inline const uint160 operator & ( const base_uint160 & a , const base_uint160 & b ) { return uint160 ( a ) & = b ; }
inline const uint160 operator | ( const base_uint160 & a , const base_uint160 & b ) { return uint160 ( a ) | = b ; }
inline const uint160 operator + ( const base_uint160 & a , const base_uint160 & b ) { return uint160 ( a ) + = b ; }
inline const uint160 operator - ( const base_uint160 & a , const base_uint160 & b ) { return uint160 ( a ) - = b ; }
inline bool operator < ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a < ( base_uint160 ) b ; }
inline bool operator < = ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a < = ( base_uint160 ) b ; }
inline bool operator > ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a > ( base_uint160 ) b ; }
inline bool operator > = ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a > = ( base_uint160 ) b ; }
inline bool operator = = ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a = = ( base_uint160 ) b ; }
inline bool operator ! = ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a ! = ( base_uint160 ) b ; }
inline const uint160 operator ^ ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a ^ ( base_uint160 ) b ; }
inline const uint160 operator & ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a & ( base_uint160 ) b ; }
inline const uint160 operator | ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a | ( base_uint160 ) b ; }
inline const uint160 operator + ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a + ( base_uint160 ) b ; }
inline const uint160 operator - ( const base_uint160 & a , const uint160 & b ) { return ( base_uint160 ) a - ( base_uint160 ) b ; }
inline bool operator < ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a < ( base_uint160 ) b ; }
inline bool operator < = ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a < = ( base_uint160 ) b ; }
inline bool operator > ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a > ( base_uint160 ) b ; }
inline bool operator > = ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a > = ( base_uint160 ) b ; }
inline bool operator = = ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a = = ( base_uint160 ) b ; }
inline bool operator ! = ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a ! = ( base_uint160 ) b ; }
inline const uint160 operator ^ ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a ^ ( base_uint160 ) b ; }
inline const uint160 operator & ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a & ( base_uint160 ) b ; }
inline const uint160 operator | ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a | ( base_uint160 ) b ; }
inline const uint160 operator + ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a + ( base_uint160 ) b ; }
inline const uint160 operator - ( const uint160 & a , const base_uint160 & b ) { return ( base_uint160 ) a - ( base_uint160 ) b ; }
inline bool operator < ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a < ( base_uint160 ) b ; }
inline bool operator < = ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a < = ( base_uint160 ) b ; }
inline bool operator > ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a > ( base_uint160 ) b ; }
inline bool operator > = ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a > = ( base_uint160 ) b ; }
inline bool operator = = ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a = = ( base_uint160 ) b ; }
inline bool operator ! = ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a ! = ( base_uint160 ) b ; }
inline const uint160 operator ^ ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a ^ ( base_uint160 ) b ; }
inline const uint160 operator & ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a & ( base_uint160 ) b ; }
inline const uint160 operator | ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a | ( base_uint160 ) b ; }
inline const uint160 operator + ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a + ( base_uint160 ) b ; }
inline const uint160 operator - ( const uint160 & a , const uint160 & b ) { return ( base_uint160 ) a - ( base_uint160 ) b ; }
//////////////////////////////////////////////////////////////////////////////
//
// uint256
//
/** 256-bit unsigned integer */
class uint256 : public base_uint256
{
/** 256-bit unsigned big integer. */
class uint256 : public base_uint < 256 > {
public :
typedef base_uint256 basetype ;
uint256 ( )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
uint256 ( const basetype & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
}
uint256 & operator = ( const basetype & b )
{
for ( int i = 0 ; i < WIDTH ; i + + )
pn [ i ] = b . pn [ i ] ;
return * this ;
}
uint256 ( uint64_t b )
{
pn [ 0 ] = ( unsigned int ) b ;
pn [ 1 ] = ( unsigned int ) ( b > > 32 ) ;
for ( int i = 2 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
}
uint256 & operator = ( uint64_t b )
{
pn [ 0 ] = ( unsigned int ) b ;
pn [ 1 ] = ( unsigned int ) ( b > > 32 ) ;
for ( int i = 2 ; i < WIDTH ; i + + )
pn [ i ] = 0 ;
uint256 ( ) { }
uint256 ( const base_uint < 256 > & b ) : base_uint < 256 > ( b ) { }
uint256 ( uint64_t b ) : base_uint < 256 > ( b ) { }
explicit uint256 ( const std : : string & str ) : base_uint < 256 > ( str ) { }
explicit uint256 ( const std : : vector < unsigned char > & vch ) : base_uint < 256 > ( vch ) { }
// The "compact" format is a representation of a whole
// number N using an unsigned 32bit number similar to a
// floating point format.
// The most significant 8 bits are the unsigned exponent of base 256.
// This exponent can be thought of as "number of bytes of N".
// The lower 23 bits are the mantissa.
// Bit number 24 (0x800000) represents the sign of N.
// N = (-1^sign) * mantissa * 256^(exponent-3)
//
// Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
// MPI uses the most significant bit of the first byte as sign.
// Thus 0x1234560000 is compact (0x05123456)
// and 0xc0de000000 is compact (0x0600c0de)
// (0x05c0de00) would be -0x40de000000
//
// Bitcoin only uses this "compact" format for encoding difficulty
// targets, which are unsigned 256bit quantities. Thus, all the
// complexities of the sign bit and using base 256 are probably an
// implementation accident.
//
// This implementation directly uses shifts instead of going
// through an intermediate MPI representation.
uint256 & SetCompact ( uint32_t nCompact , bool * pfNegative = NULL , bool * pfOverflow = NULL )
{
int nSize = nCompact > > 24 ;
uint32_t nWord = nCompact & 0x007fffff ;
if ( nSize < = 3 )
{
nWord > > = 8 * ( 3 - nSize ) ;
* this = nWord ;
}
else
{
* this = nWord ;
* this < < = 8 * ( nSize - 3 ) ;
}
if ( pfNegative )
* pfNegative = nWord ! = 0 & & ( nCompact & 0x00800000 ) ! = 0 ;
if ( pfOverflow )
* pfOverflow = nWord ! = 0 & & ( ( nSize > 34 ) | |
( nWord > 0xff & & nSize > 33 ) | |
( nWord > 0xffff & & nSize > 32 ) ) ;
return * this ;
}
explicit uint256 ( const std : : string & str )
{
SetHex ( str ) ;
}
explicit uint256 ( const std : : vector < unsigned char > & vch )
uint32_t GetCompact ( bool fNegative = false ) const
{
if ( vch . size ( ) = = sizeof ( pn ) )
memcpy ( pn , & vch [ 0 ] , sizeof ( pn ) ) ;
int nSize = ( bits ( ) + 7 ) / 8 ;
uint32_t nCompact = 0 ;
if ( nSize < = 3 )
nCompact = GetLow64 ( ) < < 8 * ( 3 - nSize ) ;
else
* this = 0 ;
{
uint256 bn = * this > > 8 * ( nSize - 3 ) ;
nCompact = bn . GetLow64 ( ) ;
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if ( nCompact & 0x00800000 )
{
nCompact > > = 8 ;
nSize + + ;
}
assert ( ( nCompact & ~ 0x007fffff ) = = 0 ) ;
assert ( nSize < 256 ) ;
nCompact | = nSize < < 24 ;
nCompact | = ( fNegative & & ( nCompact & 0x007fffff ) ? 0x00800000 : 0 ) ;
return nCompact ;
}
} ;
inline bool operator = = ( const uint256 & a , uint64_t b ) { return ( base_uint256 ) a = = b ; }
inline bool operator ! = ( const uint256 & a , uint64_t b ) { return ( base_uint256 ) a ! = b ; }
inline const uint256 operator < < ( const base_uint256 & a , unsigned int shift ) { return uint256 ( a ) < < = shift ; }
inline const uint256 operator > > ( const base_uint256 & a , unsigned int shift ) { return uint256 ( a ) > > = shift ; }
inline const uint256 operator < < ( const uint256 & a , unsigned int shift ) { return uint256 ( a ) < < = shift ; }
inline const uint256 operator > > ( const uint256 & a , unsigned int shift ) { return uint256 ( a ) > > = shift ; }
inline const uint256 operator ^ ( const base_uint256 & a , const base_uint256 & b ) { return uint256 ( a ) ^ = b ; }
inline const uint256 operator & ( const base_uint256 & a , const base_uint256 & b ) { return uint256 ( a ) & = b ; }
inline const uint256 operator | ( const base_uint256 & a , const base_uint256 & b ) { return uint256 ( a ) | = b ; }
inline const uint256 operator + ( const base_uint256 & a , const base_uint256 & b ) { return uint256 ( a ) + = b ; }
inline const uint256 operator - ( const base_uint256 & a , const base_uint256 & b ) { return uint256 ( a ) - = b ; }
inline bool operator < ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a < ( base_uint256 ) b ; }
inline bool operator < = ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a < = ( base_uint256 ) b ; }
inline bool operator > ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a > ( base_uint256 ) b ; }
inline bool operator > = ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a > = ( base_uint256 ) b ; }
inline bool operator = = ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a = = ( base_uint256 ) b ; }
inline bool operator ! = ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a ! = ( base_uint256 ) b ; }
inline const uint256 operator ^ ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a ^ ( base_uint256 ) b ; }
inline const uint256 operator & ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a & ( base_uint256 ) b ; }
inline const uint256 operator | ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a | ( base_uint256 ) b ; }
inline const uint256 operator + ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a + ( base_uint256 ) b ; }
inline const uint256 operator - ( const base_uint256 & a , const uint256 & b ) { return ( base_uint256 ) a - ( base_uint256 ) b ; }
inline bool operator < ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a < ( base_uint256 ) b ; }
inline bool operator < = ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a < = ( base_uint256 ) b ; }
inline bool operator > ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a > ( base_uint256 ) b ; }
inline bool operator > = ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a > = ( base_uint256 ) b ; }
inline bool operator = = ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a = = ( base_uint256 ) b ; }
inline bool operator ! = ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a ! = ( base_uint256 ) b ; }
inline const uint256 operator ^ ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a ^ ( base_uint256 ) b ; }
inline const uint256 operator & ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a & ( base_uint256 ) b ; }
inline const uint256 operator | ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a | ( base_uint256 ) b ; }
inline const uint256 operator + ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a + ( base_uint256 ) b ; }
inline const uint256 operator - ( const uint256 & a , const base_uint256 & b ) { return ( base_uint256 ) a - ( base_uint256 ) b ; }
inline bool operator < ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a < ( base_uint256 ) b ; }
inline bool operator < = ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a < = ( base_uint256 ) b ; }
inline bool operator > ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a > ( base_uint256 ) b ; }
inline bool operator > = ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a > = ( base_uint256 ) b ; }
inline bool operator = = ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a = = ( base_uint256 ) b ; }
inline bool operator ! = ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a ! = ( base_uint256 ) b ; }
inline const uint256 operator ^ ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a ^ ( base_uint256 ) b ; }
inline const uint256 operator & ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a & ( base_uint256 ) b ; }
inline const uint256 operator | ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a | ( base_uint256 ) b ; }
inline const uint256 operator + ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a + ( base_uint256 ) b ; }
inline const uint256 operator - ( const uint256 & a , const uint256 & b ) { return ( base_uint256 ) a - ( base_uint256 ) b ; }
# endif