Best way to create Bignum from C extension

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

On Sep 25, 1:32 pm, Tom W. [email protected] wrote:

Fuzed (fuzed.rubyforge.org)

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 wrote:

in other words, reversing the array and flatting it would produce the
Chronic (chronic.rubyforge.org)

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

On Wed, Sep 26, 2007 at 02:32:08AM +0900, Tom W. wrote:

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

On Sep 26, 2:49 pm, Tom W. [email protected] wrote:

  • Libraries:
    No, the reason I need to do this is to read in Erlang’s packed data
    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…