From: Dave Pederson Date: 2007-08-24T15:28:26+09:00 Subject: Inverse Square Root ------=_Part_10743_12974781.1187936904737 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello- I was wondering if it is possible to include the quake fast inverse square root function in ruby? I think all you would have to do is add the following method to math.c /* * call-seq: * Math.isqrt(numeric) => float * * Returns the inverse square root of numeric. */ static VALUE math_isqrt(obj, y) VALUE obj, y; { float x; Need_Float(y); x = (float) RFLOAT(y)->value; float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i >> 1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return rb_float_new(x); } Then, further down, add the following: rb_define_module_function(rb_mMath, "isqrt", math_isqrt, 1); I added the code to my local source copy of 1.8.6 then ran make and make install. Finally, I ran the following ruby script: #!/usr/bin/ruby -w for i in 0..20 print i print " - " puts Math.isqrt(i) end Which gave the following results (which seem correct): 0 - 1.98177537096858e+19 1 - 0.998307168483734 2 - 0.706930041313171 3 - 0.576846837997437 4 - 0.499153584241867 5 - 0.447141021490097 6 - 0.407681375741959 7 - 0.377444177865982 8 - 0.353465020656586 9 - 0.332953214645386 10 - 0.315685778856277 11 - 0.301036149263382 12 - 0.288423418998718 13 - 0.277312487363815 14 - 0.267214089632034 15 - 0.25775083899498 16 - 0.249576792120934 17 - 0.242388844490051 18 - 0.235677853226662 19 - 0.229414582252502 20 - 0.223570510745049 Cheers, -Dave ------=_Part_10743_12974781.1187936904737 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello-

I was wondering if it is possible to include the quake fast inverse square root function in ruby?  I think all you would have to do is add the following method to math.c

/*
 *  call-seq:
 *     Math.isqrt (numeric)    => float
 *
 *  Returns the inverse square root of <i>numeric</i>.
 */
static VALUE
math_isqrt(obj, y)
    VALUE obj, y;
{
    float x;

    Need_Float(y);
    x = (float) RFLOAT(y)->value;
    float xhalf = 0.5f*x;
    int i = *(int*)&x;
    i = 0x5f3759df - (i >> 1);
    x = *(float*)&i;
    x = x*(1.5f - xhalf*x*x);
    return rb_float_new(x);
}

Then, further down, add the following:

    rb_define_module_function(rb_mMath, "isqrt", math_isqrt, 1);


I added the code to my local source copy of 1.8.6 then ran make and make install.  Finally, I ran the following ruby script:

#!/usr/bin/ruby -w
for i in 0..20
  print i
  print " - "
  puts Math.isqrt(i)
end

Which gave the following results (which seem correct):

0 - 1.98177537096858e+19
1 - 0.998307168483734
2 - 0.706930041313171
3 - 0.576846837997437
4 - 0.499153584241867
5 - 0.447141021490097
6 - 0.407681375741959
7 - 0.377444177865982
8 - 0.353465020656586
9 - 0.332953214645386
10 - 0.315685778856277
11 - 0.301036149263382
12 - 0.288423418998718
13 - 0.277312487363815
14 - 0.267214089632034
15 - 0.25775083899498
16 - 0.249576792120934
17 - 0.242388844490051
18 - 0.235677853226662
19 - 0.229414582252502
20 - 0.223570510745049

Cheers,

-Dave
------=_Part_10743_12974781.1187936904737--