# Best way to create Bignum from C extension

**URL:** <https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913>\
**Category:** ruby-talk\
**Created:** [25 September 2007 17:32 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913 "2007-09-25T17:32:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tom\_Werner](https://avatars.discourse-cdn.com/v4/letter/t/e9c0ed/32.png) [@Tom\_Werner](https://rubytalk.org/u/Tom_Werner)\
**Post date:** [25 September 2007 17:32 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913/1 "2007-09-25T17:32:08Z")

</div>

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:  
> &nbsp;&nbsp;&nbsp;&nbsp;Chronic ([chronic.rubyforge.org](http://chronic.rubyforge.org))  
> &nbsp;&nbsp;&nbsp;&nbsp;God ([god.rubyforge.org](http://god.rubyforge.org))  
> &nbsp;&nbsp;&nbsp;&nbsp;Fuzed ([fuzed.rubyforge.org](http://fuzed.rubyforge.org))  
> \* Site:  
> &nbsp;&nbsp;&nbsp;&nbsp;[rubyisawesome.com](http://rubyisawesome.com)

---

<div class="post-metadata">

**Author:** ![Tom\_M](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@Tom\_M](https://rubytalk.org/u/Tom_M)\
**Post date:** [26 September 2007 18:40 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913/2 "2007-09-26T18:40:14Z")

</div>

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

> **···**
>
> On Sep 25, 1:32 pm, Tom Werner \<pub...@rubyisawesome.com\> 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:  
> > &nbsp;&nbsp;&nbsp;&nbsp;Chronic (chronic.rubyforge.org)  
> > &nbsp;&nbsp;&nbsp;&nbsp;God (god.rubyforge.org)  
> > &nbsp;&nbsp;&nbsp;&nbsp;Fuzed (fuzed.rubyforge.org)  
> > \* Site:  
> > &nbsp;&nbsp;&nbsp;&nbsp;rubyisawesome.com

---

<div class="post-metadata">

**Author:** ![Paul\_Brannan](https://avatars.discourse-cdn.com/v4/letter/p/76d3ee/32.png) [@Paul\_Brannan](https://rubytalk.org/u/Paul_Brannan)\
**Post date:** [28 September 2007 15:03 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913/3 "2007-09-28T15:03:33Z")

</div>

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

Paul

> **···**
>
> 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.

---

<div class="post-metadata">

**Author:** ![Tom\_Werner](https://avatars.discourse-cdn.com/v4/letter/t/e9c0ed/32.png) [@Tom\_Werner](https://rubytalk.org/u/Tom_Werner)\
**Post date:** [26 September 2007 18:49 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913/4 "2007-09-26T18:49:29Z")

</div>

Tom M wrote:

> **···**
>
> > On Sep 25, 1:32 pm, Tom Werner \<pub...@rubyisawesome.com\> wrote:  
> > &nbsp;&nbsp;
> > 
> > > 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:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;Chronic (chronic.rubyforge.org)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;God (god.rubyforge.org)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;Fuzed (fuzed.rubyforge.org)  
> > > \* Site:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;rubyisawesome.com  
> > > &nbsp;&nbsp;&nbsp;&nbsp;  
> > > 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:  
> &nbsp;&nbsp;&nbsp;&nbsp;Chronic (chronic.rubyforge.org)  
> &nbsp;&nbsp;&nbsp;&nbsp;God (god.rubyforge.org)  
> &nbsp;&nbsp;&nbsp;&nbsp;Fuzed (fuzed.rubyforge.org)  
> \* Site:  
> &nbsp;&nbsp;&nbsp;&nbsp;rubyisawesome.com

---

<div class="post-metadata">

**Author:** ![Tom\_M](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@Tom\_M](https://rubytalk.org/u/Tom_M)\
**Post date:** [26 September 2007 19:45 UTC](https://rubytalk.org/t/best-way-to-create-bignum-from-c-extension/40913/5 "2007-09-26T19:45:03Z")

</div>

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

> **···**
>
> On Sep 26, 2:49 pm, Tom Werner \<pub...@rubyisawesome.com\> wrote:
> 
> > Tom M wrote:  
> > \> On Sep 25, 1:32 pm, Tom Werner \<pub...@rubyisawesome.com\> 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:  
> > &nbsp;&nbsp;&nbsp;&nbsp;Chronic (chronic.rubyforge.org)  
> > &nbsp;&nbsp;&nbsp;&nbsp;God (god.rubyforge.org)  
> > &nbsp;&nbsp;&nbsp;&nbsp;Fuzed (fuzed.rubyforge.org)  
> > \* Site:  
> > &nbsp;&nbsp;&nbsp;&nbsp;rubyisawesome.com
