Getting more than one implicit conversion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Cory Nelson

    #1

    Getting more than one implicit conversion

    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?

  • Daniel T.

    #2
    Re: Getting more than one implicit conversion

    In article <1140324357.520 033.302230@g44g 2000cwa.googleg roups.com>,
    "Cory Nelson" <phrosty@gmail. com> wrote:
    [color=blue]
    > 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?[/color]

    Make one explicit. unit512 = uint128( 0 );

    --
    Magic depends on tradition and belief. It does not welcome observation,
    nor does it profit by experiment. On the other hand, science is based
    on experience; it is open to correction by observation and experiment.

    Comment

    • Cory Nelson

      #3
      Re: Getting more than one implicit conversion

      Indeed, that's what I'm doing right now, but I'm hoping to find a
      better way.

      Comment

      • Greg

        #4
        Re: Getting more than one implicit conversion


        Cory Nelson wrote:[color=blue]
        > 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?[/color]

        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

        Comment

        • Kai-Uwe Bux

          #5
          Re: Getting more than one implicit conversion

          Cory Nelson wrote:
          [color=blue]
          > 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?[/color]

          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


          Comment

          • Greg

            #6
            Re: Getting more than one implicit conversion

            Cory Nelson wrote:[color=blue]
            > 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?[/color]

            Declare a helper subclass to perform the conversion:

            struct uint512FromUnsi gnedLong : public uint512
            {
            uint512FromUnsi gnedLong(unsign ed long ul)
            : uint512( uint256( uint128(ul)))
            {
            }
            };

            Usage:

            int main()
            {
            uint512FromUnsi gnedLong bigInt = 42;

            uint512 bigInt2;

            bigInt2 = uint512FromUnsi gnedLong(12);

            Greg

            Comment

            • Greg

              #7
              Re: Getting more than one implicit conversion

              Cory Nelson wrote:[color=blue]
              > 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?[/color]

              Declare a helper subclass with the appropriate converting constructor:

              struct uint512FromUnsi gnedLong : public uint512
              {
              uint512FromUnsi gnedLong(unsign ed long ul)
              : uint512( uint256( uint128(ul)))
              {
              }
              };


              Here are two examples of the helper subclass in use:

              int main()
              {
              uint512FromUnsi gnedLong bigInt = 42;

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

              // can also assign a ulong to an uint512:

              uint512 bigInt2;

              bigInt2 = uint512FromUnsi gnedLong(12);

              Greg

              Comment

              • Cory Nelson

                #8
                Re: Getting more than one implicit conversion

                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.

                Comment

                • Greg

                  #9
                  Re: Getting more than one implicit conversion

                  Cory Nelson wrote:[color=blue]
                  > 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.[/color]

                  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>(u nsigned long n)
                  {
                  return uint128(n);
                  }

                  typedef large_integer<u int512> uint1024;

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

                  Comment

                  Working...