PageRenderTime 28ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/test/jruby/test_big_decimal.rb

http://github.com/jruby/jruby
Ruby | 386 lines | 283 code | 72 blank | 31 comment | 0 complexity | 4e8a1a96363d29e04e2dfbd9aa725aea MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, GPL-2.0, JSON, LGPL-2.1
  1. require 'test/unit'
  2. require 'bigdecimal'
  3. class TestBigDecimal < Test::Unit::TestCase
  4. def test_bad_to_s_format_strings
  5. bd = BigDecimal.new("1")
  6. assert_equal("0.1E1", bd.to_s)
  7. assert_equal("+0.1E1", bd.to_s("+-2"))
  8. assert_equal("0.23", BigDecimal.new("0.23").to_s("F"))
  9. end
  10. def test_no_singleton_methods_on_bigdecimal
  11. num = BigDecimal.new("0.001")
  12. assert_raise(TypeError) { class << num ; def amethod ; end ; end }
  13. assert_raise(TypeError) { def num.amethod ; end }
  14. end
  15. def test_can_instantiate_big_decimal
  16. assert_nothing_raised {BigDecimal.new("4")}
  17. assert_nothing_raised {BigDecimal.new("3.14159")}
  18. end
  19. def test_can_implicitly_instantiate_big_decimal
  20. # JRUBY-153 issues
  21. assert_nothing_raised {BigDecimal("4")}
  22. assert_nothing_raised {BigDecimal("3.14159")}
  23. end
  24. def test_alphabetic_args_return_zero
  25. assert_equal( BigDecimal("0.0"), BigDecimal("XXX"),
  26. 'Big Decimal objects instanitiated with a value that starts
  27. with a letter should have a value of 0.0' )
  28. end
  29. class X
  30. def to_str; "3.14159" end
  31. end
  32. def test_can_accept_arbitrary_objects_as_arguments
  33. # as log as the object has a #to_str method...
  34. x = X.new
  35. assert_nothing_raised { BigDecimal.new(x) }
  36. assert_nothing_raised { BigDecimal(x) }
  37. end
  38. def test_cmp
  39. begin
  40. BigDecimal.new('10') < "foo"
  41. rescue ArgumentError => e
  42. assert_equal 'comparison of BigDecimal with String failed', e.message
  43. else
  44. fail 'expected cmp to fail'
  45. end
  46. begin
  47. BigDecimal.new('10') >= nil
  48. rescue ArgumentError => e
  49. assert_equal 'comparison of BigDecimal with nil failed', e.message
  50. else
  51. fail 'expected cmp to fail'
  52. end
  53. end
  54. class MyNum
  55. def *(other)
  56. 33
  57. end
  58. def /(other)
  59. 99
  60. end
  61. def coerce(other)
  62. [MyNum.new, self]
  63. end
  64. end
  65. def test_coerce_div_mul
  66. require 'bigdecimal/util'
  67. assert_equal 33, BigDecimal.new('10') * MyNum.new
  68. assert_equal 99, 10.0 / MyNum.new
  69. assert_equal 99, 10.0.to_d / MyNum.new
  70. end
  71. require "bigdecimal/newton"
  72. include Newton
  73. class Function
  74. def initialize()
  75. @zero = BigDecimal::new("0.0")
  76. @one = BigDecimal::new("1.0")
  77. @two = BigDecimal::new("2.0")
  78. @ten = BigDecimal::new("10.0")
  79. @eps = BigDecimal::new("1.0e-16")
  80. end
  81. def zero;@zero;end
  82. def one ;@one ;end
  83. def two ;@two ;end
  84. def ten ;@ten ;end
  85. def eps ;@eps ;end
  86. def values(x) # <= defines functions solved
  87. f = []
  88. f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0
  89. f2 = x[0] - x[1] # f2 = x - y => 0
  90. f <<= f1
  91. f <<= f2
  92. f
  93. end
  94. end
  95. def test_newton_extension
  96. f = BigDecimal::limit(100)
  97. f = Function.new
  98. x = [f.zero,f.zero] # Initial values
  99. n = nlsolve(f,x)
  100. expected = [BigDecimal('0.1000000000262923315461642086010446338567975310185638386446002778855192224707966221794469725479649528E1'),
  101. BigDecimal('0.1000000000262923315461642086010446338567975310185638386446002778855192224707966221794469725479649528E1')]
  102. assert_equal expected, x
  103. end
  104. require "bigdecimal/math.rb"
  105. include BigMath
  106. def test_math_extension
  107. expected = BigDecimal('0.31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066453462141417033006060218E1')
  108. # this test fails under C Ruby
  109. # ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.9.1]
  110. assert_equal expected, PI(100)
  111. zero= BigDecimal("0")
  112. one = BigDecimal("1")
  113. two = BigDecimal("2")
  114. three = BigDecimal("3")
  115. assert_equal one * 1, one
  116. assert_equal one / 1, one
  117. assert_equal one + 1, two
  118. assert_equal one - 1, zero
  119. assert_equal zero, one % 1
  120. assert_equal one, three % two
  121. assert_equal BigDecimal("0.2"), BigDecimal("2.2") % two
  122. assert_equal BigDecimal("0.003"), BigDecimal("15.993") % BigDecimal("15.99")
  123. assert_equal 1*one, one
  124. assert_equal 1/one, one
  125. assert_equal 1+one, BigDecimal("2")
  126. assert_equal 1-one, BigDecimal("0")
  127. assert_equal one * 1.0, 1.0
  128. assert_equal one / 1.0, 1.0
  129. assert_equal one + 1.0, 2.0
  130. assert_equal one - 1.0, 0.0
  131. assert_equal 1.0*one, 1.0
  132. assert_equal 1.0/one, 1.0
  133. assert_equal 1.0+one, 2.0
  134. assert_equal 1.0-one, 0.0
  135. assert_equal("1.0", BigDecimal.new('1.0').to_s('F'))
  136. assert_equal("0.0", BigDecimal.new('0.0').to_s)
  137. assert_equal(BigDecimal("2"), BigDecimal("1.5").round)
  138. assert_equal(BigDecimal("15"), BigDecimal("15").round)
  139. assert_equal(BigDecimal("20"), BigDecimal("15").round(-1))
  140. assert_equal(BigDecimal("0"), BigDecimal("15").round(-2))
  141. assert_equal(BigDecimal("-10"), BigDecimal("-15").round(-1, BigDecimal::ROUND_CEILING))
  142. assert_equal(BigDecimal("10"), BigDecimal("15").round(-1, BigDecimal::ROUND_HALF_DOWN))
  143. assert_equal(BigDecimal("20"), BigDecimal("25").round(-1, BigDecimal::ROUND_HALF_EVEN))
  144. assert_equal(BigDecimal("15.99"), BigDecimal("15.993").round(2))
  145. assert_equal(BigDecimal("1"), BigDecimal("1.8").round(0, BigDecimal::ROUND_DOWN))
  146. assert_equal(BigDecimal("2"), BigDecimal("1.2").round(0, BigDecimal::ROUND_UP))
  147. assert_equal(BigDecimal("-1"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_CEILING))
  148. assert_equal(BigDecimal("-2"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_FLOOR))
  149. assert_equal(BigDecimal("-2"), BigDecimal("-1.5").round(0, BigDecimal::ROUND_FLOOR))
  150. assert_equal(BigDecimal("1"), BigDecimal("1.5").round(0, BigDecimal::ROUND_HALF_DOWN))
  151. assert_equal(BigDecimal("2"), BigDecimal("1.5").round(0, BigDecimal::ROUND_HALF_EVEN))
  152. assert_equal(BigDecimal("2"), BigDecimal("2.5").round(0, BigDecimal::ROUND_HALF_EVEN))
  153. end
  154. def test_round_nan
  155. nan = BigDecimal.new('NaN')
  156. assert nan.round.nan? # nothing raised
  157. assert nan.round(0).nan?
  158. assert nan.round(2).nan?
  159. end
  160. def test_big_decimal_power
  161. require 'bigdecimal/math'
  162. n = BigDecimal("10")
  163. assert_equal(n.power(0), BigDecimal("1"))
  164. assert_equal(n.power(1), n)
  165. assert_equal(n.power(2), BigDecimal("100"))
  166. assert_equal(n.power(-1), BigDecimal("0.1"))
  167. n.power(1.1)
  168. begin
  169. n.power('1.1')
  170. rescue TypeError => e
  171. assert_equal 'wrong argument type String (expected scalar Numeric)', e.message
  172. else
  173. fail 'expected to raise TypeError'
  174. end
  175. assert_equal BigDecimal('0.1E2'), n.power(1.0)
  176. res = n.power(1.1)
  177. #assert_equal BigDecimal('0.125892541E2'), res
  178. # NOTE: we're not handling precision the same as MRI with pow
  179. assert_equal '0.125892541', res.to_s[0..10]
  180. assert_equal 'E2', res.to_s[-2..-1]
  181. res = 2 ** BigDecimal(1.2, 2)
  182. #assert_equal BigDecimal('0.229739671E1'), res
  183. # NOTE: we're not handling precision the same as MRI with pow
  184. assert_equal '0.22973967', res.to_s[0..9]
  185. assert_equal 'E1', res.to_s[-2..-1]
  186. res = BigDecimal(1.2, 2) ** 2.0
  187. assert_equal BigDecimal('0.144E1'), res
  188. end
  189. def teardown
  190. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) rescue nil
  191. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) rescue nil
  192. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) rescue nil
  193. end
  194. def test_big_decimal_mode
  195. # Accept valid arguments to #mode
  196. assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
  197. assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW,true)
  198. assert BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW,false)
  199. # Reject invalid arguments to #mode
  200. assert_raises(TypeError) { BigDecimal.mode(true) } # first argument must be a Fixnum
  201. assert_raises(ArgumentError) { BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, 1) } # second argument must be [true|false]
  202. assert_raises(TypeError) { BigDecimal.mode(512) } # first argument must be == 256, or return non-zero when AND-ed with 255
  203. # exception mode defaults to 0
  204. assert_equal 0, BigDecimal.mode(1) # value of first argument doesn't matter when retrieving the current exception mode, as long as it's a Fixnum <= 255
  205. # set and clear a single exception mode
  206. assert_equal BigDecimal::EXCEPTION_INFINITY, BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  207. assert_equal 0, BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  208. assert_equal BigDecimal::EXCEPTION_NaN, BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true)
  209. assert_equal 0, BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  210. # set a composition of exception modes separately, make sure the final result is the composited value
  211. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  212. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true)
  213. assert_equal BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)
  214. # reset the exception mode to 0 for the following tests
  215. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  216. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  217. # set a composition of exception modes with one call and retrieve it using the retrieval idiom
  218. # note: this is to check compatibility with MRI, which currently sets only the last mode
  219. # it checks for
  220. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, true)
  221. assert_equal BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)
  222. # rounding mode defaults to BigDecimal::ROUND_HALF_UP
  223. assert_equal BigDecimal::ROUND_HALF_UP, BigDecimal.mode(BigDecimal::ROUND_MODE)
  224. # make sure each setting complete replaces any previous setting
  225. [BigDecimal::ROUND_UP, BigDecimal::ROUND_DOWN, BigDecimal::ROUND_CEILING, BigDecimal::ROUND_FLOOR,
  226. BigDecimal::ROUND_HALF_UP, BigDecimal::ROUND_HALF_DOWN, BigDecimal::ROUND_HALF_EVEN].each do |mode|
  227. assert_equal mode, BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
  228. end
  229. # reset rounding mode to 0 for following tests
  230. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
  231. assert_raises(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, true) } # second argument must be a Fixnum
  232. assert_raises(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 8) } # any Fixnum >= 8 should trigger this error, as the valid rounding modes are currently [0..6]
  233. end
  234. def test_marshaling
  235. f = 123.456
  236. bd = BigDecimal.new(f.to_s)
  237. bd_serialized = Marshal.dump(bd)
  238. assert_equal f, Marshal.restore(bd_serialized).to_f
  239. end
  240. #JRUBY-2272
  241. def test_marshal_regression
  242. assert_equal BigDecimal('0.0'), Marshal.load(Marshal.dump(BigDecimal.new('0.0')))
  243. end
  244. def test_large_bigdecimal_to_f
  245. pos_inf = BigDecimal.new("5E69999999").to_f
  246. assert pos_inf.infinite?
  247. assert pos_inf > 0
  248. assert BigDecimal.new("0E69999999").to_f < Float::EPSILON
  249. neg_inf = BigDecimal.new("-5E69999999").to_f
  250. assert neg_inf.infinite?
  251. assert neg_inf < 0
  252. assert BigDecimal.new("5E-69999999").to_f < Float::EPSILON
  253. end
  254. def test_infinity
  255. assert_equal true, BigDecimal.new("0.0000000001").finite?
  256. #if RUBY_VERSION > '1.9'
  257. # assert_raises(FloatDomainError) { BigDecimal("Infinity") }
  258. # assert_raises(FloatDomainError) { BigDecimal("+Infinity") }
  259. # assert_raises(FloatDomainError) { BigDecimal("-Infinity") }
  260. #else
  261. assert_equal 1, BigDecimal("Infinity").infinite?
  262. assert_equal false, BigDecimal("-Infinity").finite?
  263. assert_equal false, BigDecimal("+Infinity").finite?
  264. #end
  265. assert_raises(TypeError) { BigDecimal(:"+Infinity") }
  266. assert_equal BigDecimal('0'), BigDecimal("infinity")
  267. assert_equal BigDecimal('0'), BigDecimal("+Infinit")
  268. end
  269. #JRUBY-5190
  270. def test_large_precisions
  271. a = BigDecimal("1").div(BigDecimal("3"), 307)
  272. b = BigDecimal("1").div(BigDecimal("3"), 308)
  273. assert_equal a.to_f, b.to_f
  274. end
  275. # GH-644, GH-648
  276. def test_div_by_float_precision_gh644
  277. a = BigDecimal.new(11023) / 2.2046
  278. assert_equal 5_000, a.to_f
  279. end
  280. def test_div_by_float_precision_gh648
  281. b = BigDecimal.new(1.05, 10) / 1.48
  282. assert (b.to_f - 0.7094594594594595) < Float::EPSILON
  283. end
  284. def test_GH_2650
  285. assert_equal(BigDecimal.new("10.91231", 1).to_f, 10.91231)
  286. assert_equal(BigDecimal.new("10.9", 2).to_f, 10.9)
  287. end
  288. # GH-3527
  289. def test_tail_junk
  290. b = BigDecimal.new("5-6")
  291. assert_equal BigDecimal('5'), b
  292. b = BigDecimal.new("100+42")
  293. assert_equal 100, b.to_i
  294. end
  295. class BigDeci < BigDecimal
  296. # MRI does not invoke initialize on 1.8./1.9
  297. def initialize(arg); raise super(arg.to_s) end
  298. def abs; -super end
  299. def infinite?; false end
  300. end
  301. def test_subclass
  302. a = BigDeci.new 1.to_s
  303. assert_equal(-1, a.abs)
  304. assert_equal false, a.infinite?
  305. a = BigDeci.new '-100'
  306. assert_equal(-5, a.div(20))
  307. assert_equal(-100, a.abs)
  308. assert a.inspect.index('#<BigDecimal:')
  309. assert_equal '-0.1E3', a.to_s
  310. assert_equal BigDeci, a.class
  311. assert a.is_a?(BigDeci)
  312. assert a.kind_of?(BigDeci)
  313. end
  314. end