mathn の課題はそれはそれとして、1.9 ではこの場合、やはり mathn しなくて
も複素数を返したほうがいいのではないかという気がしています。

この変更をしても、「以前は例外だったものがそうではなくなった」というよ
うな変化はありません。NaN ではなく、ましな値が返ります。1.9 では、
Complex があるので、不思議ではないと思います。

[ruby-math:00543] でも、一律に Complex を返すことに異議があって、必要な
場合には、むしろ Complex を返してほしい、という事らしいので、その要望に
沿うと思います。

# 複素数を返す場合をもっと絞っていいのかもしれませんが、こんなところで。


Index: numeric.c
===================================================================
--- numeric.c	(revision 19415)
+++ numeric.c	(working copy)
@@ -794,6 +794,8 @@
       case T_BIGNUM:
 	return DBL2NUM(pow(RFLOAT_VALUE(x), rb_big2dbl(y)));
       case T_FLOAT:
+	if (RFLOAT_VALUE(x) < 0)
+	  return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
 	return DBL2NUM(pow(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
       default:
 	return rb_num_coerce_bin(x, y, rb_intern("**"));
@@ -2484,6 +2486,8 @@
 	    return DBL2NUM(RFLOAT_VALUE(y) < 0 ? (1.0 / zero) : 0.0);
 	}
 	if (a == 1) return DBL2NUM(1.0);
+	if (a < 0)
+	    return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
 	return DBL2NUM(pow((double)a, RFLOAT_VALUE(y)));
       default:
 	return rb_num_coerce_bin(x, y, rb_intern("**"));
Index: bignum.c
===================================================================
--- bignum.c	(revision 19415)
+++ bignum.c	(working copy)
@@ -2098,6 +2098,8 @@
     if (y == INT2FIX(0)) return INT2FIX(1);
     switch (TYPE(y)) {
       case T_FLOAT:
+	if (rb_funcall(x, '<', 1, INT2FIX(0)))
+	    return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
 	d = RFLOAT_VALUE(y);
 	break;