mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
bigdecimal.c: check underflow
* ext/bigdecimal/bigdecimal.c (BigDecimal_to_f): check underflow since strtod() sets errno to ERANGE at underflow too. [ruby-core:47342] [Bug #6944] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36854 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
aa7dc0f305
commit
d7ca01a73a
3 changed files with 36 additions and 8 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Thu Aug 30 16:17:52 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (BigDecimal_to_f): check underflow since
|
||||||
|
strtod() sets errno to ERANGE at underflow too. [ruby-core:47342]
|
||||||
|
[Bug #6944]
|
||||||
|
|
||||||
Thu Aug 30 12:44:43 2012 Akinori MUSHA <knu@iDaemons.org>
|
Thu Aug 30 12:44:43 2012 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* lib/set.rb (Set#{<,>,<=,>=}): Define comparison operators as
|
* lib/set.rb (Set#{<,>,<=,>=}): Define comparison operators as
|
||||||
|
|
|
@ -696,8 +696,10 @@ BigDecimal_to_f(VALUE self)
|
||||||
VpToString(p, buf, 0, 0);
|
VpToString(p, buf, 0, 0);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
d = strtod(buf, 0);
|
d = strtod(buf, 0);
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE) {
|
||||||
goto overflow;
|
if (d == 0.0) goto underflow;
|
||||||
|
if (fabs(d) >= HUGE_VAL) goto overflow;
|
||||||
|
}
|
||||||
return rb_float_new(d);
|
return rb_float_new(d);
|
||||||
|
|
||||||
overflow:
|
overflow:
|
||||||
|
|
|
@ -540,15 +540,35 @@ class TestBigDecimal < Test::Unit::TestCase
|
||||||
assert_kind_of(Float, x .to_f)
|
assert_kind_of(Float, x .to_f)
|
||||||
assert_kind_of(Float, (-x).to_f)
|
assert_kind_of(Float, (-x).to_f)
|
||||||
|
|
||||||
|
bug6944 = '[ruby-core:47342]'
|
||||||
|
|
||||||
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
|
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
|
||||||
assert_raise(FloatDomainError) {
|
x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
|
||||||
BigDecimal("1e#{Float::MIN_10_EXP - 2*Float::DIG}").to_f }
|
assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
|
||||||
assert_raise(FloatDomainError) {
|
x = "-#{x}"
|
||||||
BigDecimal("-1e#{Float::MIN_10_EXP - 2*Float::DIG}").to_f }
|
assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
|
||||||
|
x = "1e#{Float::MIN_10_EXP - Float::DIG}"
|
||||||
|
assert_nothing_raised(FloatDomainError, x) {
|
||||||
|
assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
|
||||||
|
}
|
||||||
|
x = "-#{x}"
|
||||||
|
assert_nothing_raised(FloatDomainError, x) {
|
||||||
|
assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
|
||||||
|
}
|
||||||
|
|
||||||
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false)
|
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false)
|
||||||
assert_equal( 0.0, BigDecimal("1e#{Float::MIN_10_EXP - 2*Float::DIG}").to_f)
|
x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
|
||||||
assert_equal(-0.0, BigDecimal("-1e#{Float::MIN_10_EXP - 2*Float::DIG}").to_f)
|
assert_equal( 0.0, BigDecimal(x).to_f, x)
|
||||||
|
x = "-#{x}"
|
||||||
|
assert_equal(-0.0, BigDecimal(x).to_f, x)
|
||||||
|
x = "1e#{Float::MIN_10_EXP - Float::DIG}"
|
||||||
|
assert_nothing_raised(FloatDomainError, x) {
|
||||||
|
assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
|
||||||
|
}
|
||||||
|
x = "-#{x}"
|
||||||
|
assert_nothing_raised(FloatDomainError, x) {
|
||||||
|
assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_coerce
|
def test_coerce
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue