aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-08-28 08:52:14 +0000
committermrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-08-28 08:52:14 +0000
commita2bf9203e8b74065eb1452dd13741b3de7305eaf (patch)
tree5752281613cd54bb02b0668359a9429adede5422
parentb6595225c1a68f212eb2d11f35de7732b9114fd7 (diff)
downloadruby-a2bf9203e8b74065eb1452dd13741b3de7305eaf.tar.gz
* ext/bigdecimal/bigdecimal.c (BigDecimal_save_exception_mode,
BigDecimal_save_rounding_mode, BigDecimal_save_limit): added. * test/bigdecimal/test_bigdecimal.rb: added tests for the above features. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29127 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--ext/bigdecimal/bigdecimal.c46
-rw-r--r--test/bigdecimal/test_bigdecimal.rb36
3 files changed, 90 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 56b57329f5..434df4ed63 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Aug 28 17:39:33 2010 Kenta Murata <mrkn@mrkn.jp>
+
+ * ext/bigdecimal/bigdecimal.c (BigDecimal_save_exception_mode,
+ BigDecimal_save_rounding_mode, BigDecimal_save_limit): added.
+
+ * test/bigdecimal/test_bigdecimal.rb: added tests for the above
+ features.
+
Sat Aug 28 08:11:05 2010 Tanaka Akira <akr@fsij.org>
* ext/pathname/pathname.c (path_blockdev_p): Pathname#blockdev?
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index c0d42e07dc..776615e089 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -1800,6 +1800,48 @@ BigDecimal_sign(VALUE self)
return INT2FIX(s);
}
+/* call-seq:
+ * BigDecimal.save_exception_mode { ... }
+ */
+static VALUE
+BigDecimal_save_exception_mode(VALUE self)
+{
+ unsigned short const exception_mode = VpGetException();
+ int state;
+ VALUE ret = rb_protect(rb_yield, Qnil, &state);
+ VpSetException(exception_mode);
+ if (state) rb_jump_tag(state);
+ return ret;
+}
+
+/* call-seq:
+ * BigDecimal.save_rounding_mode { ... }
+ */
+static VALUE
+BigDecimal_save_rounding_mode(VALUE self)
+{
+ unsigned short const round_mode = VpGetRoundMode();
+ int state;
+ VALUE ret = rb_protect(rb_yield, Qnil, &state);
+ VpSetRoundMode(round_mode);
+ if (state) rb_jump_tag(state);
+ return Qnil;
+}
+
+/* call-seq:
+ * BigDecimal.save_limit { ... }
+ */
+static VALUE
+BigDecimal_save_limit(VALUE self)
+{
+ size_t const limit = VpGetPrecLimit();
+ int state;
+ VALUE ret = rb_protect(rb_yield, Qnil, &state);
+ VpSetPrecLimit(limit);
+ if (state) rb_jump_tag(state);
+ return Qnil;
+}
+
/* Document-class: BigDecimal
* BigDecimal provides arbitrary-precision floating point decimal arithmetic.
*
@@ -1926,6 +1968,10 @@ Init_bigdecimal(void)
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
rb_define_singleton_method(rb_cBigDecimal, "ver", BigDecimal_version, 0);
+ rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0);
+ rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0);
+ rb_define_singleton_method(rb_cBigDecimal, "save_limit", BigDecimal_save_limit, 0);
+
/* Constants definition */
/*
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index 7411416043..02a067a810 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -77,6 +77,42 @@ class TestBigDecimal < Test::Unit::TestCase
end
end
+ def test_save_exception_mode
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+ mode = BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
+ BigDecimal.save_exception_mode do
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
+ end
+ assert_equal(mode, BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW))
+
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
+ BigDecimal.save_exception_mode do
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
+ end
+ assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
+ end
+
+ def test_save_rounding_mode
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
+ BigDecimal.save_rounding_mode do
+ BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
+ end
+ assert_equal(BigDecimal::ROUND_FLOOR, BigDecimal.mode(BigDecimal::ROUND_MODE))
+ end
+
+ def test_save_limit
+ begin
+ old = BigDecimal.limit
+ BigDecimal.limit(100)
+ BigDecimal.save_limit do
+ BigDecimal.limit(200)
+ end
+ assert_equal(100, BigDecimal.limit);
+ ensure
+ BigDecimal.limit(old)
+ end
+ end
+
def test_exception_nan
_test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal.new("NaN") }
end