tags:

views:

65

answers:

2

this is copied from http://www.zenspider.com/ZSS/Products/RubyInline/Readme.html, the "home" of rubyinline, adding/moding as indicated in the comments

require 'rubygems' #added this, doesn't run otherwise
require 'inline'
class MyTest

  def factorial(n)
    f = 1
    n.downto(2) { |x| f *= x }
    f
  end

  inline do |builder|
    builder.c "
    long factorial_c(int max) {
      int i=max, result=1;
      while (i >= 2) { result *= i--; }
      return result;
    }"
  end
end

#t = MyTest.new()  # removed this
#factorial_5 = t.factorial(5) # removed this

asdf = MyTest.new # added this
puts "ruby native factorial: " + asdf.factorial(16).to_s # added this
puts "inline factorial: " + asdf.factorial_c(16).to_s # added this

when I run it, I get

ruby testfact.rb

ruby native factorial: 20922789888000

inline factorial: 2004189184

the ruby version is correct; I don't know what the inline version is (other than incorrect).

I'm running ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]; I installed rubyinline like this: sudo gem install RubyInline

I tried changing the "int"'s to "long"'s in the C code, but it didn't make a diff. (I'm not a C programmer, if that wasn't already apparent.)

Finally, I noticed that if I run them both with 12 or less as the argument, they both yield the same answer. Things get weird at 13 and above.

TIA

A: 

In the version of C you have is a long 32 bits or 64 bits? A long is not always larger than an int in C.

John Meagher
I don't know. I'm running ubuntu 9.04, the default C for that. Changed the "int"s to "double"s, that did it. Knew it had to be something simple. Thanks for pointing me in the right direction.
You can also try "long long". See http://gcc.gnu.org/onlinedocs/gcc/Long-Long.html for info.
John Meagher
That (long long) fixed it for arg's up to 21. Thanks!
+1  A: 

Your C ints are definitely 32 bits.

2 to the 32nd power is 4294967296.

20922789888000 mod 4294967296 is 2004189184.

John Y