mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Import changes from ruby/bigdecimal (#2531)
Sync to ruby/bigdecimal@92356ba71c
This commit is contained in:
parent
59c3b1c9c8
commit
dd0c75fdc2
Notes:
git
2019-10-08 09:06:54 +09:00
Merged-By: mrkn <mrkn@ruby-lang.org>
11 changed files with 93 additions and 98 deletions
|
@ -1756,12 +1756,15 @@ BigDecimal_fix(VALUE self)
|
|||
* round(n, mode)
|
||||
*
|
||||
* Round to the nearest integer (by default), returning the result as a
|
||||
* BigDecimal.
|
||||
* BigDecimal if n is specified, or as an Integer if it isn't.
|
||||
*
|
||||
* BigDecimal('3.14159').round #=> 3
|
||||
* BigDecimal('8.7').round #=> 9
|
||||
* BigDecimal('-9.9').round #=> -10
|
||||
*
|
||||
* BigDecimal('3.14159').round(2).class.name #=> "BigDecimal"
|
||||
* BigDecimal('3.14159').round.class.name #=> "Integer"
|
||||
*
|
||||
* If n is specified and positive, the fractional part of the result has no
|
||||
* more than that many digits.
|
||||
*
|
||||
|
@ -2585,7 +2588,7 @@ opts_exception_p(VALUE opts)
|
|||
#endif
|
||||
|
||||
static Real *
|
||||
BigDecimal_new(int argc, VALUE *argv)
|
||||
VpNewVarArg(int argc, VALUE *argv)
|
||||
{
|
||||
size_t mf;
|
||||
VALUE opts = Qnil;
|
||||
|
@ -2726,7 +2729,7 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self)
|
|||
if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
|
||||
}
|
||||
obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
|
||||
pv = BigDecimal_new(argc, argv);
|
||||
pv = VpNewVarArg(argc, argv);
|
||||
if (pv == NULL) return Qnil;
|
||||
SAVE(pv);
|
||||
if (ToValue(pv)) pv = VpCopy(NULL, pv);
|
||||
|
@ -2735,6 +2738,20 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self)
|
|||
return pv->obj = obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
BigDecimal_s_interpret_loosely(VALUE klass, VALUE str)
|
||||
{
|
||||
ENTER(1);
|
||||
char const *c_str;
|
||||
Real *pv;
|
||||
|
||||
c_str = StringValueCStr(str);
|
||||
GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
|
||||
pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
|
||||
RB_OBJ_FREEZE(pv->obj);
|
||||
return pv->obj;
|
||||
}
|
||||
|
||||
/* call-seq:
|
||||
* BigDecimal.limit(digits)
|
||||
*
|
||||
|
@ -2954,6 +2971,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|||
n = prec + rmpd_double_figures();
|
||||
negative = BIGDECIMAL_NEGATIVE_P(vx);
|
||||
if (negative) {
|
||||
VALUE x_zero = INT2NUM(1);
|
||||
VALUE x_copy = f_BigDecimal(1, &x_zero, klass);
|
||||
x = BigDecimal_initialize_copy(x_copy, x);
|
||||
vx = DATA_PTR(x);
|
||||
VpSetSign(vx, 1);
|
||||
}
|
||||
|
||||
|
@ -3155,20 +3176,6 @@ get_vp_value:
|
|||
return y;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rmpd_util_str_to_d(VALUE str)
|
||||
{
|
||||
ENTER(1);
|
||||
char const *c_str;
|
||||
Real *pv;
|
||||
|
||||
c_str = StringValueCStr(str);
|
||||
GUARD_OBJ(pv, VpAlloc(0, c_str, 0, 1));
|
||||
pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
|
||||
RB_OBJ_FREEZE(pv->obj);
|
||||
return pv->obj;
|
||||
}
|
||||
|
||||
/* Document-class: BigDecimal
|
||||
* BigDecimal provides arbitrary-precision floating point decimal arithmetic.
|
||||
*
|
||||
|
@ -3315,6 +3322,7 @@ Init_bigdecimal(void)
|
|||
/* Class methods */
|
||||
rb_undef_method(CLASS_OF(rb_cBigDecimal), "allocate");
|
||||
rb_undef_method(CLASS_OF(rb_cBigDecimal), "new");
|
||||
rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1);
|
||||
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
|
||||
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
||||
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
||||
|
@ -4296,7 +4304,7 @@ VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
|
|||
|
||||
psz[i] = '\0';
|
||||
|
||||
if (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0)) {
|
||||
if (strict_p && (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0))) {
|
||||
VALUE str;
|
||||
invalid_value:
|
||||
if (!strict_p) {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
EXPORTS
|
||||
rmpd_util_str_to_d
|
||||
Init_bigdecimal
|
|
@ -1,6 +1,6 @@
|
|||
# coding: utf-8
|
||||
|
||||
bigdecimal_version = '1.4.2'
|
||||
bigdecimal_version = '2.0.0.dev'
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "bigdecimal"
|
||||
|
@ -14,16 +14,11 @@ Gem::Specification.new do |s|
|
|||
s.license = "ruby"
|
||||
|
||||
s.require_paths = %w[lib]
|
||||
s.extensions = %w[ext/bigdecimal/extconf.rb ext/bigdecimal/util/extconf.rb]
|
||||
s.extensions = %w[ext/bigdecimal/extconf.rb]
|
||||
s.files = %w[
|
||||
bigdecimal.gemspec
|
||||
ext/bigdecimal/bigdecimal.c
|
||||
ext/bigdecimal/bigdecimal.def
|
||||
ext/bigdecimal/bigdecimal.h
|
||||
ext/bigdecimal/depend
|
||||
ext/bigdecimal/extconf.rb
|
||||
ext/bigdecimal/util/extconf.rb
|
||||
ext/bigdecimal/util/util.c
|
||||
lib/bigdecimal.rb
|
||||
lib/bigdecimal/jacobian.rb
|
||||
lib/bigdecimal/ludcmp.rb
|
||||
|
@ -39,7 +34,6 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.add_development_dependency "rake", "~> 10.0"
|
||||
s.add_development_dependency "rake-compiler", ">= 0.9"
|
||||
s.add_development_dependency "rake-compiler-dock", ">= 0.6.1"
|
||||
s.add_development_dependency "minitest", "< 5.0.0"
|
||||
s.add_development_dependency "pry"
|
||||
end
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
# frozen_string_literal: false
|
||||
require 'mkmf'
|
||||
|
||||
def check_bigdecimal_version(gemspec_path)
|
||||
message "checking RUBY_BIGDECIMAL_VERSION... "
|
||||
|
||||
bigdecimal_version =
|
||||
IO.readlines(gemspec_path)
|
||||
.grep(/\Abigdecimal_version\s+=\s+/)[0][/\'([^\']+)\'/, 1]
|
||||
|
||||
version_components = bigdecimal_version.split('.')
|
||||
bigdecimal_version = version_components[0, 3].join('.')
|
||||
bigdecimal_version << "-#{version_components[3]}" if version_components[3]
|
||||
$defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"]
|
||||
|
||||
message "#{bigdecimal_version}\n"
|
||||
end
|
||||
|
||||
gemspec_name = gemspec_path = nil
|
||||
unless ['', '../../'].any? {|dir|
|
||||
gemspec_name = "#{dir}bigdecimal.gemspec"
|
||||
|
@ -11,11 +26,7 @@ unless ['', '../../'].any? {|dir|
|
|||
abort
|
||||
end
|
||||
|
||||
bigdecimal_version =
|
||||
IO.readlines(gemspec_path)
|
||||
.grep(/\Abigdecimal_version\s+=\s+/)[0][/\'([\d\.]+)\'/, 1]
|
||||
|
||||
$defs << %Q[-DRUBY_BIGDECIMAL_VERSION=\\"#{bigdecimal_version}\\"]
|
||||
check_bigdecimal_version(gemspec_path)
|
||||
|
||||
have_func("labs", "stdlib.h")
|
||||
have_func("llabs", "stdlib.h")
|
||||
|
|
|
@ -1,6 +1 @@
|
|||
require 'bigdecimal.so'
|
||||
|
||||
def BigDecimal.new(*args, **kwargs)
|
||||
warn "BigDecimal.new is deprecated; use BigDecimal() method instead.", uplevel: 1
|
||||
BigDecimal(*args, **kwargs)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: false
|
||||
#
|
||||
|
||||
require 'bigdecimal'
|
||||
|
||||
# require 'bigdecimal/jacobian'
|
||||
#
|
||||
# Provides methods to compute the Jacobian matrix of a set of equations at a
|
||||
|
@ -21,9 +23,6 @@
|
|||
#
|
||||
# fx is f.values(x).
|
||||
#
|
||||
|
||||
require 'bigdecimal'
|
||||
|
||||
module Jacobian
|
||||
module_function
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#++
|
||||
|
||||
require 'bigdecimal'
|
||||
require 'bigdecimal/util.so'
|
||||
|
||||
class Integer < Numeric
|
||||
# call-seq:
|
||||
|
@ -66,6 +65,9 @@ class String
|
|||
#
|
||||
# See also BigDecimal::new.
|
||||
#
|
||||
def to_d
|
||||
BigDecimal.interpret_loosely(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# frozen_string_literal: false
|
||||
require 'mkmf'
|
||||
|
||||
checking_for(checking_message("Windows")) do
|
||||
case RUBY_PLATFORM
|
||||
when /cygwin|mingw/
|
||||
if ARGV.include?('-rdevkit') # check `rake -rdevkit compile` case
|
||||
base_dir = File.expand_path('../../../..', __FILE__)
|
||||
build_dir = File.join(base_dir, "tmp", RUBY_PLATFORM, "bigdecimal", RUBY_VERSION, "")
|
||||
else
|
||||
build_dir = "$(TARGET_SO_DIR)../"
|
||||
end
|
||||
$libs << " #{build_dir}bigdecimal.so"
|
||||
true
|
||||
when /mswin/
|
||||
$DLDFLAGS << " -libpath:.."
|
||||
$libs << " bigdecimal-$(arch).lib"
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
create_makefile('bigdecimal/util')
|
|
@ -1,9 +0,0 @@
|
|||
#include "ruby.h"
|
||||
|
||||
RUBY_EXTERN VALUE rmpd_util_str_to_d(VALUE str);
|
||||
|
||||
void
|
||||
Init_util(void)
|
||||
{
|
||||
rb_define_method(rb_cString, "to_d", rmpd_util_str_to_d, 0);
|
||||
}
|
|
@ -77,6 +77,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_BigDecimal_bug7522
|
||||
bd = BigDecimal("1.12", 1)
|
||||
assert_same(bd, BigDecimal(bd))
|
||||
assert_same(bd, BigDecimal(bd, exception: false))
|
||||
assert_not_same(bd, BigDecimal(bd, 1))
|
||||
assert_not_same(bd, BigDecimal(bd, 1, exception: false))
|
||||
end
|
||||
|
||||
def test_BigDecimal_with_invalid_string
|
||||
[
|
||||
'', '.', 'e1', 'd1', '.e', '.d', '1.e', '1.d', '.1e', '.1d',
|
||||
|
@ -222,16 +230,30 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_s_new
|
||||
# TODO: BigDecimal.new will be removed on 1.5
|
||||
# assert_raise_with_message(NoMethodError, /undefined method `new'/) { BigDecimal.new("1") }
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
assert_equal(BigDecimal(1), BigDecimal.new(1))
|
||||
assert_raise(ArgumentError) { BigDecimal.new(',', exception: true) }
|
||||
assert_nothing_raised { assert_equal(nil, BigDecimal.new(',', exception: false)) }
|
||||
assert_raise(TypeError) { BigDecimal.new(nil, exception: true) }
|
||||
assert_nothing_raised { assert_equal(nil, BigDecimal.new(nil, exception: false)) }
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
assert_raise_with_message(NoMethodError, /undefined method `new'/) { BigDecimal.new("1") }
|
||||
end
|
||||
|
||||
def test_s_interpret_loosely
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1__1_1"))
|
||||
assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5"))
|
||||
assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5 degrees"))
|
||||
assert_equal(BigDecimal('2.5e1'), BigDecimal.interpret_loosely("2.5e1 degrees"))
|
||||
assert_equal(BigDecimal('0'), BigDecimal.interpret_loosely("degrees 100.0"))
|
||||
assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5"))
|
||||
assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5__"))
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1_.125"))
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1._125"))
|
||||
assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1__2_5"))
|
||||
assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1_e10"))
|
||||
assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1e_10"))
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("0.1e1__0"))
|
||||
assert_equal(BigDecimal('1.2'), BigDecimal.interpret_loosely("1.2.3"))
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1."))
|
||||
assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1e"))
|
||||
|
||||
assert_equal(BigDecimal('0.0'), BigDecimal.interpret_loosely("invalid"))
|
||||
|
||||
assert(BigDecimal.interpret_loosely("2.5").frozen?)
|
||||
end
|
||||
|
||||
def _test_mode(type)
|
||||
|
@ -1597,6 +1619,13 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_exp_with_negative
|
||||
x = BigDecimal(-1)
|
||||
y = BigMath.exp(x, 20)
|
||||
assert_equal(y, BigMath.exp(-1, 20))
|
||||
assert_equal(BigDecimal(-1), x)
|
||||
end
|
||||
|
||||
def test_exp_with_negative_infinite
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
|
@ -1833,18 +1862,9 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_dup_subclass
|
||||
def test_new_subclass
|
||||
c = Class.new(BigDecimal)
|
||||
# TODO: BigDecimal.new will be removed on 1.5
|
||||
# assert_raise_with_message(NoMethodError, /undefined method `new'/) { c.new(1) }
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
assert_equal(BigDecimal(1), c.new(1))
|
||||
assert_raise(ArgumentError) { c.new(',', exception: true) }
|
||||
assert_nothing_raised { assert_equal(nil, c.new(',', exception: false)) }
|
||||
assert_raise(TypeError) { c.new(nil, exception: true) }
|
||||
assert_nothing_raised { assert_equal(nil, c.new(nil, exception: false)) }
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
assert_raise_with_message(NoMethodError, /undefined method `new'/) { c.new(1) }
|
||||
end
|
||||
|
||||
def test_to_d
|
||||
|
|
|
@ -75,6 +75,8 @@ class TestBigDecimalUtil < Test::Unit::TestCase
|
|||
assert_equal(BigDecimal('0.1'), "0.1e_10".to_d)
|
||||
assert_equal(BigDecimal('1'), "0.1e1__0".to_d)
|
||||
assert_equal(BigDecimal('1.2'), "1.2.3".to_d)
|
||||
assert_equal(BigDecimal('1'), "1.".to_d)
|
||||
assert_equal(BigDecimal('1'), "1e".to_d)
|
||||
|
||||
assert("2.5".to_d.frozen?)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue