diff --git a/ChangeLog b/ChangeLog index ff3e466a23..0599328997 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Jun 22 23:35:43 2004 NAKAMURA Usaku + + * sprintf.c (rb_f_sprintf): support FZERO and FSPACE with NaN/Inf. + + * test/ruby/test_sprintf.rb (test_nan, test_inf): add tests. + Tue Jun 22 21:11:36 2004 Masaki Suketa * ext/win32ole/win32ole.c (OLE_FREE): should not call CoFreeUnuse- diff --git a/sprintf.c b/sprintf.c index be22578a8d..17bcce1330 100644 --- a/sprintf.c +++ b/sprintf.c @@ -698,7 +698,7 @@ rb_f_sprintf(argc, argv) expr = "Inf"; } need = strlen(expr); - if (fval < 0.0 || (flags & FPLUS)) + if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS)) need++; if ((flags & FWIDTH) && need < width) need = width; @@ -706,14 +706,34 @@ rb_f_sprintf(argc, argv) CHECK(need); sprintf(&buf[blen], "%*s", need, ""); if (flags & FMINUS) { - if (fval < 0.0) + if (!isnan(fval) && fval < 0.0) buf[blen++] = '-'; else if (flags & FPLUS) buf[blen++] = '+'; + else if (flags & FSPACE) + blen++; + strncpy(&buf[blen], expr, strlen(expr)); + } + else if (flags & FZERO) { + if (!isnan(fval) && fval < 0.0) { + buf[blen++] = '-'; + need--; + } + else if (flags & FPLUS) { + buf[blen++] = '+'; + need--; + } + else if (flags & FSPACE) { + blen++; + need--; + } + while (need-- - strlen(expr) > 0) { + buf[blen++] = '0'; + } strncpy(&buf[blen], expr, strlen(expr)); } else { - if (fval < 0.0) + if (!isnan(fval) && fval < 0.0) buf[blen + need - strlen(expr) - 1] = '-'; else if (flags & FPLUS) buf[blen + need - strlen(expr) - 1] = '+'; diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb index 8716e7021d..c72eadb218 100644 --- a/test/ruby/test_sprintf.rb +++ b/test/ruby/test_sprintf.rb @@ -72,4 +72,70 @@ class TestSprintf < Test::Unit::TestCase assert_equal(" +0010", sprintf("%+6.4b", 2)) assert_equal(" -0001", sprintf("%+6.4b", -1)) end + + def test_nan + nan = 0.0 / 0.0 + assert_equal("NaN", sprintf("%f", nan)) + assert_equal("NaN", sprintf("%-f", nan)) + assert_equal("+NaN", sprintf("%+f", nan)) + + assert_equal(" NaN", sprintf("%8f", nan)) + assert_equal("NaN ", sprintf("%-8f", nan)) + assert_equal(" +NaN", sprintf("%+8f", nan)) + + assert_equal("00000NaN", sprintf("%08f", nan)) + assert_equal("NaN ", sprintf("%-08f", nan)) + assert_equal("+0000NaN", sprintf("%+08f", nan)) + + assert_equal(" NaN", sprintf("% 8f", nan)) + assert_equal(" NaN ", sprintf("%- 8f", nan)) + assert_equal(" +NaN", sprintf("%+ 8f", nan)) + + assert_equal(" 0000NaN", sprintf("% 08f", nan)) + assert_equal(" NaN ", sprintf("%- 08f", nan)) + assert_equal("+0000NaN", sprintf("%+ 08f", nan)) + end + + def test_inf + inf = 1.0 / 0.0 + assert_equal("Inf", sprintf("%f", inf)) + assert_equal("Inf", sprintf("%-f", inf)) + assert_equal("+Inf", sprintf("%+f", inf)) + + assert_equal(" Inf", sprintf("%8f", inf)) + assert_equal("Inf ", sprintf("%-8f", inf)) + assert_equal(" +Inf", sprintf("%+8f", inf)) + + assert_equal("00000Inf", sprintf("%08f", inf)) + assert_equal("Inf ", sprintf("%-08f", inf)) + assert_equal("+0000Inf", sprintf("%+08f", inf)) + + assert_equal(" Inf", sprintf("% 8f", inf)) + assert_equal(" Inf ", sprintf("%- 8f", inf)) + assert_equal(" +Inf", sprintf("%+ 8f", inf)) + + assert_equal(" 0000Inf", sprintf("% 08f", inf)) + assert_equal(" Inf ", sprintf("%- 08f", inf)) + assert_equal("+0000Inf", sprintf("%+ 08f", inf)) + + assert_equal("-Inf", sprintf("%f", -inf)) + assert_equal("-Inf", sprintf("%-f", -inf)) + assert_equal("-Inf", sprintf("%+f", -inf)) + + assert_equal(" -Inf", sprintf("%8f", -inf)) + assert_equal("-Inf ", sprintf("%-8f", -inf)) + assert_equal(" -Inf", sprintf("%+8f", -inf)) + + assert_equal("-0000Inf", sprintf("%08f", -inf)) + assert_equal("-Inf ", sprintf("%-08f", -inf)) + assert_equal("-0000Inf", sprintf("%+08f", -inf)) + + assert_equal(" -Inf", sprintf("% 8f", -inf)) + assert_equal("-Inf ", sprintf("%- 8f", -inf)) + assert_equal(" -Inf", sprintf("%+ 8f", -inf)) + + assert_equal("-0000Inf", sprintf("% 08f", -inf)) + assert_equal("-Inf ", sprintf("%- 08f", -inf)) + assert_equal("-0000Inf", sprintf("%+ 08f", -inf)) + end end