西松と申します。

練習がてらnumeric.cにFloat#copysignを書き加えてみました。
こんなことができます:
$ ./miniruby -e 'p 32.1.copysign(1.0)'
32.1
$ ./miniruby -e 'p 32.1.copysign(0.0)'
32.1
$ ./miniruby -e 'p 32.1.copysign(-0.0)'
-32.1
$ ./miniruby -e 'p 32.1.copysign('-0.0')'
-32.1
$ ./miniruby -e 'p 32.1.copysign('123')'
32.1
$ ./miniruby -e 'p 32.1.copysign('-123')'
-32.1
$ ./miniruby -e 'p 32.1.copysign(-123)'
-32.1
$ ./miniruby -e 'p -32.1.copysign(0.0)'
32.1
$ ./miniruby -e 'p -32.1.copysign(Rational(1,2))'' ; echo $?
1
$ 

質問なのですが、Rationalのようなto_fが定義されているものが引数に
来たときにも動くようにするには、下のexit(1);にしているところを
どのように書けばよいのでしょうか。

あと、numeric.cのコメントに1つtypo(+→-)を見つけました。

$ svn diff
Index: numeric.c
===================================================================
--- numeric.c	(revision 22120)
+++ numeric.c	(working copy)
@@ -595,7 +595,7 @@
 
 /*
  * call-seq:
- *   float + other   => float
+ *   float - other   => float
  *
  * Returns a new float which is the difference of <code>float</code>
  * and <code>other</code>.
@@ -1141,6 +1141,44 @@
 
 /*
  *  call-seq:
+ *     x.copysign(y)   => float
+ *
+ *  Returns a value whose absolute value matches that of x, but whose sign matches that of <i>y</i>.
+ *
+ *     ( 34.56).copysign(-0.0)   #=> -34.56
+ *     (-34.56).copysign( 1.0)   #=>  34.56
+ *     (-34.56).copysign( 1  )   #=>  34.56
+ *     (-34.56).copysign( 1111111111111111111111111111111111111111111111111111111111111111111111111)
+ *                               #=>  34.56
+ *
+ */
+
+static VALUE
+flo_copysign(VALUE x, VALUE y)
+{
+    double yd, val;
+    switch (TYPE(y)) {
+      case T_FIXNUM:
+	yd = (double)FIX2LONG(y);
+	break;
+      case T_BIGNUM:
+	yd = rb_big2dbl(y);
+	break;
+      case T_FLOAT:
+	yd = RFLOAT_VALUE(y);
+	break;
+      case T_STRING:
+	yd = rb_str_to_dbl(y, Qfalse);
+	break;
+      default:
+	exit(1); /* rb_funcall(y, 'to_f', 0, 0)??? */
+    }
+    val = copysign(RFLOAT_VALUE(x),yd);
+    return DBL2NUM(val);
+}
+
+/*
+ *  call-seq:
  *     flt.zero? -> true or false
  *
  *  Returns <code>true</code> if <i>flt</i> is 0.0.
@@ -3262,6 +3300,7 @@
     rb_define_method(rb_cFloat, "hash", flo_hash, 0);
     rb_define_method(rb_cFloat, "to_f", flo_to_f, 0);
     rb_define_method(rb_cFloat, "abs", flo_abs, 0);
+    rb_define_method(rb_cFloat, "copysign", flo_copysign, 1);
     rb_define_method(rb_cFloat, "magnitude", flo_abs, 0);
     rb_define_method(rb_cFloat, "zero?", flo_zero_p, 0);