Best way to create Bignum from C extension

T

Tom Werner

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
 
T

Tom M

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...
 
T

Tom Werner

Tom said:
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
 
T

Tom M

Tom said:
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...
 
P

Paul Brannan

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
 

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

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top