From 66868abc75df7367298c8973aed1580f7d05703a Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Thu, 10 Oct 2024 17:02:47 +0900 Subject: [PATCH] Accept no digits in the fractional part (#302) fix #301 For example, "0.E-9" and "0." are accepted. FYI: `Float()`/`.to_f` will accept "0.E-9": https://bugs.ruby-lang.org/issues/20705 The current `Float` doesn't accept "0." but `.to_f` accepts "0.". --- ext/bigdecimal/bigdecimal.c | 9 ++------- test/bigdecimal/test_bigdecimal.rb | 2 ++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 6d48741..34dae9f 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -5277,7 +5277,7 @@ VP_EXPORT Real * VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) { const char *orig_szVal = szVal; - size_t i, j, ni, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc; + size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc; size_t len; char v, *psz; int sign=1; @@ -5363,13 +5363,11 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) ne = 0; /* number of digits in the exponential part */ ipf = 0; /* index of the beginning of the fractional part */ ipe = 0; /* index of the beginning of the exponential part */ - dot_seen = 0; exp_seen = 0; if (v != '\0') { /* Scanning fractional part */ if ((psz[i] = szVal[j]) == '.') { - dot_seen = 1; ++i; ++j; ipf = i; @@ -5385,9 +5383,6 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) } if (!strict_p) { v = psz[i] = '\0'; - if (nf == 0) { - dot_seen = 0; - } break; } goto invalid_value; @@ -5458,7 +5453,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) psz[i] = '\0'; - if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) { + if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) { VALUE str; invalid_value: if (!strict_p) { diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index cae3375..dbc00e5 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -74,6 +74,8 @@ def test_BigDecimal assert_equal(111, BigDecimal("1_1_1_")) assert_equal(10**(-1), BigDecimal("1E-1"), '#4825') assert_equal(1234, BigDecimal(" \t\n\r \r1234 \t\n\r \r")) + assert_equal(0.0, BigDecimal("0.")) + assert_equal(0.0E-9, BigDecimal("0.E-9")) assert_raise(ArgumentError) { BigDecimal("1", -1) } assert_raise_with_message(ArgumentError, /"1__1_1"/) { BigDecimal("1__1_1") }