From: "Michael W. Ryder" <_mwryder@...> Date: 2007-04-17T17:20:09+09:00 Subject: Re: factorial in ruby ara.t.howard@noaa.gov wrote: > On Tue, 17 Apr 2007, Trans wrote: > >> >> >> On Apr 16, 1:56 pm, "Jason Roelofs" wrote: >>> No and most likely not. >> >> Why not? Seems to me factorial is a pretty basic/common math function. >> It would be nice if written in C for speed. > > perhaps. perhaps not: > > > fortytwo: ~> cat a.rb > # > # gem install inline @ http://rubyforge.org/projects/rubyinline/ > # > require 'benchmark' > require 'rubygems' > require 'inline' > # > # setup two factorial methods, one in ruby and in using inline. the inline > # version is compiled on the fly using ruby2c and cc > # > module Math > class << self > def factorial_ruby n > f = 1 > n.downto(2){|x| f *= x } > f > end > > inline do |builder| > builder.c <<-'c' > int > factorial_inline (int max) > { > int i = max, result = 1; > while (i >= 2) > { > result *= i--; > } > return result; > } > c > end > end > end > # > # check how fast they each are. we run many times to show the differences. > # > n = 4242 > Benchmark.bm do |x| > x.report 'factorial_ruby' do > n.times{ Math.factorial_ruby 42 } > end > > x.report 'factorial_inline' do > n.times{ Math.factorial_inline 42 } > end > end > # > # now show accuracy. how many bits is a signed int again? > # > 42.times do |i| > a, b = Math.factorial_ruby(i), Math.factorial_inline(i) > p [i, a, b] > break unless a == b > end > # > # check this out. automatic bigint boxing. > # > p Math.factorial_ruby(42) > p Math.factorial_ruby(42).class > > > > > fortytwo: ~> ruby a.rb > user system total real > factorial_ruby 0.550000 0.010000 0.560000 ( 0.767810) > factorial_inline 0.010000 0.000000 0.010000 ( 0.003574) > [0, 1, 1] > [1, 1, 1] > [2, 2, 2] > [3, 6, 6] > [4, 24, 24] > [5, 120, 120] > [6, 720, 720] > [7, 5040, 5040] > [8, 40320, 40320] > [9, 362880, 362880] > [10, 3628800, 3628800] > [11, 39916800, 39916800] > [12, 479001600, 479001600] > [13, 6227020800, -215430144] > 1405006117752879898543142606244511569936384000000000 > Bignum > > > not the integer wrap from the c version - this is a case where c gets > you crap > answers real quick. you need more that just c, but also an arbitrary > precision > arithmitic library to do factorial fast. > > kind regards. > > > -a Is it possible to use long integers with rubyinline and would it make a difference with the results? Also where would I find more documentation on rubyinline? I tried to use your example program and got the gem installed but it then complained about an environment variable. I don't know if it is looking for a specific C compiler or what, I have Borland C installed and in the path.