Best way to create Bignum from C extension

Discussion in 'Ruby' started by Tom Werner, Sep 25, 2007.

  1. Tom Werner

    Tom Werner Guest

    I've been hand-translating some Ruby code into C for an extension and
    have come across the need to create and return a Bignum from the
    extension. I see that there is a macro INT2NUM that will produce a
    Bignum from long or long long, but what is the best way to create an
    arbitrarily sized Bignum from a byte array packed as:

    [a, b, c] -> (a * (256 ** 0)) + (b * (256 ** 1)) + (c * (256 ** 2))

    in other words, reversing the array and flatting it would produce the
    correct binary representation of the number.

    I tried creating a Fixnum with INT2FIX(0) and then using rb_funcalls to
    incrementally construct a Bignum, but that approach 1) didn't seem to
    work past WORD sized numbers and 2) seems like it would be awfully slow.

    --
    Tom Preston-Werner

    * Libraries:
    Chronic (chronic.rubyforge.org)
    God (god.rubyforge.org)
    Fuzed (fuzed.rubyforge.org)
    * Site:
    rubyisawesome.com
     
    Tom Werner, Sep 25, 2007
    #1
    1. Advertising

  2. Tom Werner

    Tom M Guest

    On Sep 25, 1:32 pm, Tom Werner <> wrote:
    > I've been hand-translating some Ruby code into C for an extension and
    > have come across the need to create and return a Bignum from the
    > extension. I see that there is a macro INT2NUM that will produce a
    > Bignum from long or long long, but what is the best way to create an
    > arbitrarily sized Bignum from a byte array packed as:
    >
    > [a, b, c] -> (a * (256 ** 0)) + (b * (256 ** 1)) + (c * (256 ** 2))
    >
    > in other words, reversing the array and flatting it would produce the
    > correct binary representation of the number.
    >
    > I tried creating a Fixnum with INT2FIX(0) and then using rb_funcalls to
    > incrementally construct a Bignum, but that approach 1) didn't seem to
    > work past WORD sized numbers and 2) seems like it would be awfully slow.
    >
    > --
    > Tom Preston-Werner
    >
    > * Libraries:
    > Chronic (chronic.rubyforge.org)
    > God (god.rubyforge.org)
    > Fuzed (fuzed.rubyforge.org)
    > * Site:
    > rubyisawesome.com


    dumb question probably, but could you use scientific notation style
    numbers; i.e., 1.076 * 10^10? You'd return a base as a float and an
    exponent as a fixnum, and then you could calculate it on the fly...
     
    Tom M, Sep 26, 2007
    #2
    1. Advertising

  3. Tom Werner

    Tom Werner Guest

    Tom M wrote:
    > On Sep 25, 1:32 pm, Tom Werner <> wrote:
    >
    >> I've been hand-translating some Ruby code into C for an extension and
    >> have come across the need to create and return a Bignum from the
    >> extension. I see that there is a macro INT2NUM that will produce a
    >> Bignum from long or long long, but what is the best way to create an
    >> arbitrarily sized Bignum from a byte array packed as:
    >>
    >> [a, b, c] -> (a * (256 ** 0)) + (b * (256 ** 1)) + (c * (256 ** 2))
    >>
    >> in other words, reversing the array and flatting it would produce the
    >> correct binary representation of the number.
    >>
    >> I tried creating a Fixnum with INT2FIX(0) and then using rb_funcalls to
    >> incrementally construct a Bignum, but that approach 1) didn't seem to
    >> work past WORD sized numbers and 2) seems like it would be awfully slow.
    >>
    >> --
    >> Tom Preston-Werner
    >>
    >> * Libraries:
    >> Chronic (chronic.rubyforge.org)
    >> God (god.rubyforge.org)
    >> Fuzed (fuzed.rubyforge.org)
    >> * Site:
    >> rubyisawesome.com
    >>

    >
    > dumb question probably, but could you use scientific notation style
    > numbers; i.e., 1.076 * 10^10? You'd return a base as a float and an
    > exponent as a fixnum, and then you could calculate it on the fly...
    >
    >
    >
    >


    No, the reason I need to do this is to read in Erlang's packed data
    representation. Interestingly enough, that *is* how Erlang transmits floats!

    --
    Tom Preston-Werner

    * Libraries:
    Chronic (chronic.rubyforge.org)
    God (god.rubyforge.org)
    Fuzed (fuzed.rubyforge.org)
    * Site:
    rubyisawesome.com
     
    Tom Werner, Sep 26, 2007
    #3
  4. Tom Werner

    Tom M Guest

    On Sep 26, 2:49 pm, Tom Werner <> wrote:
    > Tom M wrote:
    > > On Sep 25, 1:32 pm, Tom Werner <> wrote:

    >
    > >> I've been hand-translating some Ruby code into C for an extension and
    > >> have come across the need to create and return a Bignum from the
    > >> extension. I see that there is a macro INT2NUM that will produce a
    > >> Bignum from long or long long, but what is the best way to create an
    > >> arbitrarily sized Bignum from a byte array packed as:

    >
    > >> [a, b, c] -> (a * (256 ** 0)) + (b * (256 ** 1)) + (c * (256 ** 2))

    >
    > >> in other words, reversing the array and flatting it would produce the
    > >> correct binary representation of the number.

    >
    > >> I tried creating a Fixnum with INT2FIX(0) and then using rb_funcalls to
    > >> incrementally construct a Bignum, but that approach 1) didn't seem to
    > >> work past WORD sized numbers and 2) seems like it would be awfully slow.

    >
    > >> --
    > >> Tom Preston-Werner

    >
    > >> * Libraries:
    > >> Chronic (chronic.rubyforge.org)
    > >> God (god.rubyforge.org)
    > >> Fuzed (fuzed.rubyforge.org)
    > >> * Site:
    > >> rubyisawesome.com

    >
    > > dumb question probably, but could you use scientific notation style
    > > numbers; i.e., 1.076 * 10^10? You'd return a base as a float and an
    > > exponent as a fixnum, and then you could calculate it on the fly...

    >
    > No, the reason I need to do this is to read in Erlang's packed data
    > representation. Interestingly enough, that *is* how Erlang transmits floats!
    >
    > --
    > Tom Preston-Werner
    >
    > * Libraries:
    > Chronic (chronic.rubyforge.org)
    > God (god.rubyforge.org)
    > Fuzed (fuzed.rubyforge.org)
    > * Site:
    > rubyisawesome.com


    something like breaking up the string into substrings and then calling
    unpack on each substring, then reassemling... think 'get_more_digits'
    since you're already inclined towards Erlang...
     
    Tom M, Sep 26, 2007
    #4
  5. Tom Werner

    Paul Brannan Guest

    On Wed, Sep 26, 2007 at 02:32:08AM +0900, Tom Werner wrote:
    > I've been hand-translating some Ruby code into C for an extension and
    > have come across the need to create and return a Bignum from the
    > extension. I see that there is a macro INT2NUM that will produce a
    > Bignum from long or long long, but what is the best way to create an
    > arbitrarily sized Bignum from a byte array packed as:
    >
    > [a, b, c] -> (a * (256 ** 0)) + (b * (256 ** 1)) + (c * (256 ** 2))
    >
    > in other words, reversing the array and flatting it would produce the
    > correct binary representation of the number.
    >
    > I tried creating a Fixnum with INT2FIX(0) and then using rb_funcalls to
    > incrementally construct a Bignum, but that approach 1) didn't seem to
    > work past WORD sized numbers and 2) seems like it would be awfully slow.


    Take a look at the rb_big_* functions declared in intern.h. I think you
    can work something out using them.

    Paul
     
    Paul Brannan, Sep 28, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Glen Herrmannsfeldt

    Re: Really-bignum arithmetic

    Glen Herrmannsfeldt, Sep 9, 2003, in forum: C++
    Replies:
    2
    Views:
    364
    Glen Herrmannsfeldt
    Sep 9, 2003
  2. Glen Herrmannsfeldt

    Re: Really-bignum arithmetic

    Glen Herrmannsfeldt, Sep 8, 2003, in forum: C Programming
    Replies:
    7
    Views:
    469
    Glen Herrmannsfeldt
    Sep 9, 2003
  3. Zero
    Replies:
    6
    Views:
    345
    Martin Ambuhl
    Nov 7, 2003
  4. mike3
    Replies:
    2
    Views:
    334
    mike3
    Dec 16, 2007
  5. Paul  Moore

    Best way of debigging a C extension

    Paul Moore, Dec 11, 2008, in forum: Python
    Replies:
    6
    Views:
    368
    Paul Moore
    Dec 13, 2008
Loading...

Share This Page