PageRenderTime 30ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/test/bigdecimal/test_bigdecimal.rb

http://github.com/ruby/ruby
Ruby | 1910 lines | 1665 code | 223 blank | 22 comment | 4 complexity | 86445de190bddd9460a1c4878c241f4d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require_relative "testbase"
  3. require 'bigdecimal/math'
  4. class TestBigDecimal < Test::Unit::TestCase
  5. include TestBigDecimalBase
  6. ROUNDING_MODE_MAP = [
  7. [ BigDecimal::ROUND_UP, :up],
  8. [ BigDecimal::ROUND_DOWN, :down],
  9. [ BigDecimal::ROUND_DOWN, :truncate],
  10. [ BigDecimal::ROUND_HALF_UP, :half_up],
  11. [ BigDecimal::ROUND_HALF_UP, :default],
  12. [ BigDecimal::ROUND_HALF_DOWN, :half_down],
  13. [ BigDecimal::ROUND_HALF_EVEN, :half_even],
  14. [ BigDecimal::ROUND_HALF_EVEN, :banker],
  15. [ BigDecimal::ROUND_CEILING, :ceiling],
  16. [ BigDecimal::ROUND_CEILING, :ceil],
  17. [ BigDecimal::ROUND_FLOOR, :floor],
  18. ]
  19. def assert_nan(x)
  20. assert(x.nan?, "Expected #{x.inspect} to be NaN")
  21. end
  22. def assert_positive_infinite(x)
  23. assert(x.infinite?, "Expected #{x.inspect} to be positive infinite")
  24. assert_operator(x, :>, 0)
  25. end
  26. def assert_negative_infinite(x)
  27. assert(x.infinite?, "Expected #{x.inspect} to be negative infinite")
  28. assert_operator(x, :<, 0)
  29. end
  30. def assert_positive_zero(x)
  31. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, x.sign,
  32. "Expected #{x.inspect} to be positive zero")
  33. end
  34. def assert_negative_zero(x)
  35. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, x.sign,
  36. "Expected #{x.inspect} to be negative zero")
  37. end
  38. def test_not_equal
  39. assert_not_equal BigDecimal("1"), BigDecimal("2")
  40. end
  41. def test_BigDecimal
  42. assert_equal(1, BigDecimal("1"))
  43. assert_equal(1, BigDecimal("1", 1))
  44. assert_equal(1, BigDecimal(" 1 "))
  45. assert_equal(111, BigDecimal("1_1_1_"))
  46. assert_equal(10**(-1), BigDecimal("1E-1"), '#4825')
  47. assert_equal(1234, BigDecimal(" \t\n\r \r1234 \t\n\r \r"))
  48. bd = BigDecimal("1.12", 1)
  49. assert_same(bd, BigDecimal(bd))
  50. assert_same(bd, BigDecimal(bd, exception: false))
  51. assert_not_same(bd, BigDecimal(bd, 1))
  52. assert_not_same(bd, BigDecimal(bd, 1, exception: false))
  53. assert_raise(ArgumentError) { BigDecimal("1", -1) }
  54. assert_raise_with_message(ArgumentError, /"1__1_1"/) { BigDecimal("1__1_1") }
  55. assert_raise_with_message(ArgumentError, /"_1_1_1"/) { BigDecimal("_1_1_1") }
  56. BigDecimal.save_exception_mode do
  57. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  58. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  59. assert_positive_infinite(BigDecimal("Infinity"))
  60. assert_positive_infinite(BigDecimal("1E1111111111111111111"))
  61. assert_positive_infinite(BigDecimal(" \t\n\r \rInfinity \t\n\r \r"))
  62. assert_negative_infinite(BigDecimal("-Infinity"))
  63. assert_negative_infinite(BigDecimal(" \t\n\r \r-Infinity \t\n\r \r"))
  64. assert_nan(BigDecimal("NaN"))
  65. assert_nan(BigDecimal(" \t\n\r \rNaN \t\n\r \r"))
  66. end
  67. end
  68. def test_BigDecimal_bug7522
  69. bd = BigDecimal("1.12", 1)
  70. assert_same(bd, BigDecimal(bd))
  71. assert_same(bd, BigDecimal(bd, exception: false))
  72. assert_not_same(bd, BigDecimal(bd, 1))
  73. assert_not_same(bd, BigDecimal(bd, 1, exception: false))
  74. end
  75. def test_BigDecimal_with_invalid_string
  76. [
  77. '', '.', 'e1', 'd1', '.e', '.d', '1.e', '1.d', '.1e', '.1d',
  78. '2,30', '19,000.0', '-2,30', '-19,000.0', '+2,30', '+19,000.0',
  79. '2.3,0', '19.000,0', '-2.3,0', '-19.000,0', '+2.3,0', '+19.000,0',
  80. '2.3.0', '19.000.0', '-2.3.0', '-19.000.0', '+2.3.0', '+19.000.0',
  81. 'invlaid value', '123 xyz'
  82. ].each do |invalid_string|
  83. assert_raise_with_message(ArgumentError, %Q[invalid value for BigDecimal(): "#{invalid_string}"]) do
  84. BigDecimal(invalid_string)
  85. end
  86. end
  87. BigDecimal.save_exception_mode do
  88. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  89. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  90. assert_raise_with_message(ArgumentError, /"Infinity_"/) { BigDecimal("Infinity_") }
  91. assert_raise_with_message(ArgumentError, /"\+Infinity_"/) { BigDecimal("+Infinity_") }
  92. assert_raise_with_message(ArgumentError, /"-Infinity_"/) { BigDecimal("-Infinity_") }
  93. assert_raise_with_message(ArgumentError, /"NaN_"/) { BigDecimal("NaN_") }
  94. end
  95. end
  96. def test_BigDecimal_with_integer
  97. assert_equal(BigDecimal("1"), BigDecimal(1))
  98. assert_equal(BigDecimal("-1"), BigDecimal(-1))
  99. assert_equal(BigDecimal((2**100).to_s), BigDecimal(2**100))
  100. assert_equal(BigDecimal((-2**100).to_s), BigDecimal(-2**100))
  101. end
  102. def test_BigDecimal_with_rational
  103. assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(1.quo(3), 21))
  104. assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal(-1.quo(3), 21))
  105. assert_raise_with_message(ArgumentError, "can't omit precision for a Rational.") { BigDecimal(42.quo(7)) }
  106. end
  107. def test_BigDecimal_with_float
  108. assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
  109. assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
  110. assert_raise_with_message(ArgumentError, "can't omit precision for a Float.") { BigDecimal(4.2) }
  111. assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
  112. assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
  113. bug9214 = '[ruby-core:58858]'
  114. assert_equal(BigDecimal(-0.0, Float::DIG).sign, -1, bug9214)
  115. BigDecimal.save_exception_mode do
  116. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  117. assert_nan(BigDecimal(Float::NAN))
  118. end
  119. BigDecimal.save_exception_mode do
  120. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  121. assert_positive_infinite(BigDecimal(Float::INFINITY))
  122. assert_negative_infinite(BigDecimal(-Float::INFINITY))
  123. end
  124. end
  125. def test_BigDecimal_with_big_decimal
  126. assert_equal(BigDecimal(1), BigDecimal(BigDecimal(1)))
  127. assert_equal(BigDecimal('+0'), BigDecimal(BigDecimal('+0')))
  128. assert_equal(BigDecimal('-0'), BigDecimal(BigDecimal('-0')))
  129. BigDecimal.save_exception_mode do
  130. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  131. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  132. assert_positive_infinite(BigDecimal(BigDecimal('Infinity')))
  133. assert_negative_infinite(BigDecimal(BigDecimal('-Infinity')))
  134. assert_nan(BigDecimal(BigDecimal('NaN')))
  135. end
  136. end
  137. if RUBY_VERSION < '2.7'
  138. def test_BigDecimal_with_tainted_string
  139. Thread.new {
  140. $SAFE = 1
  141. BigDecimal('1'.taint)
  142. }.join
  143. ensure
  144. $SAFE = 0
  145. end
  146. end
  147. def test_BigDecimal_with_exception_keyword
  148. assert_raise(ArgumentError) {
  149. BigDecimal('.', exception: true)
  150. }
  151. assert_nothing_raised(ArgumentError) {
  152. assert_equal(nil, BigDecimal(".", exception: false))
  153. }
  154. assert_raise(ArgumentError) {
  155. BigDecimal("1", -1, exception: true)
  156. }
  157. assert_nothing_raised(ArgumentError) {
  158. assert_equal(nil, BigDecimal("1", -1, exception: false))
  159. }
  160. assert_raise(ArgumentError) {
  161. BigDecimal(42.quo(7), exception: true)
  162. }
  163. assert_nothing_raised(ArgumentError) {
  164. assert_equal(nil, BigDecimal(42.quo(7), exception: false))
  165. }
  166. assert_raise(ArgumentError) {
  167. BigDecimal(4.2, exception: true)
  168. }
  169. assert_nothing_raised(ArgumentError) {
  170. assert_equal(nil, BigDecimal(4.2, exception: false))
  171. }
  172. # TODO: support conversion from complex
  173. # assert_raise(RangeError) {
  174. # BigDecimal(1i, exception: true)
  175. # }
  176. # assert_nothing_raised(RangeError) {
  177. # assert_equal(nil, BigDecimal(1i, exception: false))
  178. # }
  179. assert_raise(TypeError) {
  180. BigDecimal(nil, exception: true)
  181. }
  182. assert_nothing_raised(TypeError) {
  183. assert_equal(nil, BigDecimal(nil, exception: false))
  184. }
  185. assert_nothing_raised(TypeError) {
  186. assert_equal(nil, BigDecimal(:test, exception: false))
  187. }
  188. assert_nothing_raised(TypeError) {
  189. assert_equal(nil, BigDecimal(Object.new, exception: false))
  190. }
  191. # TODO: support to_d
  192. # assert_nothing_raised(TypeError) {
  193. # o = Object.new
  194. # def o.to_d; 3.14; end
  195. # assert_equal(3.14, BigDecimal(o, exception: false))
  196. # }
  197. # assert_nothing_raised(RuntimeError) {
  198. # o = Object.new
  199. # def o.to_d; raise; end
  200. # assert_equal(nil, BigDecimal(o, exception: false))
  201. # }
  202. end
  203. def test_s_ver
  204. assert_raise_with_message(NoMethodError, /undefined method `ver'/) { BigDecimal.ver }
  205. end
  206. def test_s_allocate
  207. assert_raise_with_message(NoMethodError, /undefined method `allocate'/) { BigDecimal.allocate }
  208. end
  209. def test_s_new
  210. assert_raise_with_message(NoMethodError, /undefined method `new'/) { BigDecimal.new("1") }
  211. end
  212. def test_s_interpret_loosely
  213. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1__1_1"))
  214. assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5"))
  215. assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5 degrees"))
  216. assert_equal(BigDecimal('2.5e1'), BigDecimal.interpret_loosely("2.5e1 degrees"))
  217. assert_equal(BigDecimal('0'), BigDecimal.interpret_loosely("degrees 100.0"))
  218. assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5"))
  219. assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5__"))
  220. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1_.125"))
  221. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1._125"))
  222. assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1__2_5"))
  223. assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1_e10"))
  224. assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1e_10"))
  225. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("0.1e1__0"))
  226. assert_equal(BigDecimal('1.2'), BigDecimal.interpret_loosely("1.2.3"))
  227. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1."))
  228. assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1e"))
  229. assert_equal(BigDecimal('0.0'), BigDecimal.interpret_loosely("invalid"))
  230. assert(BigDecimal.interpret_loosely("2.5").frozen?)
  231. end
  232. def _test_mode(type)
  233. BigDecimal.mode(type, true)
  234. assert_raise(FloatDomainError) { yield }
  235. BigDecimal.mode(type, false)
  236. assert_nothing_raised { yield }
  237. end
  238. def test_mode
  239. assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
  240. assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
  241. assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, :xyzzy) }
  242. assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
  243. begin
  244. saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
  245. [ BigDecimal::ROUND_UP,
  246. BigDecimal::ROUND_DOWN,
  247. BigDecimal::ROUND_HALF_UP,
  248. BigDecimal::ROUND_HALF_DOWN,
  249. BigDecimal::ROUND_CEILING,
  250. BigDecimal::ROUND_FLOOR,
  251. BigDecimal::ROUND_HALF_EVEN,
  252. ].each do |mode|
  253. BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
  254. assert_equal(mode, BigDecimal.mode(BigDecimal::ROUND_MODE))
  255. end
  256. ensure
  257. BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
  258. end
  259. BigDecimal.save_rounding_mode do
  260. ROUNDING_MODE_MAP.each do |const, sym|
  261. BigDecimal.mode(BigDecimal::ROUND_MODE, sym)
  262. assert_equal(const, BigDecimal.mode(BigDecimal::ROUND_MODE))
  263. end
  264. end
  265. end
  266. def test_thread_local_mode
  267. begin
  268. saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
  269. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
  270. Thread.start {
  271. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
  272. assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
  273. }.join
  274. assert_equal(BigDecimal::ROUND_UP, BigDecimal.mode(BigDecimal::ROUND_MODE))
  275. ensure
  276. BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
  277. end
  278. end
  279. def test_save_exception_mode
  280. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  281. mode = BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
  282. BigDecimal.save_exception_mode do
  283. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
  284. end
  285. assert_equal(mode, BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW))
  286. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
  287. BigDecimal.save_exception_mode do
  288. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
  289. end
  290. assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
  291. assert_equal(42, BigDecimal.save_exception_mode { 42 })
  292. end
  293. def test_save_rounding_mode
  294. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
  295. BigDecimal.save_rounding_mode do
  296. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
  297. end
  298. assert_equal(BigDecimal::ROUND_FLOOR, BigDecimal.mode(BigDecimal::ROUND_MODE))
  299. assert_equal(42, BigDecimal.save_rounding_mode { 42 })
  300. end
  301. def test_save_limit
  302. begin
  303. old = BigDecimal.limit
  304. BigDecimal.limit(100)
  305. BigDecimal.save_limit do
  306. BigDecimal.limit(200)
  307. end
  308. assert_equal(100, BigDecimal.limit);
  309. ensure
  310. BigDecimal.limit(old)
  311. end
  312. assert_equal(42, BigDecimal.save_limit { 42 })
  313. end
  314. def test_exception_nan
  315. _test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal("NaN") }
  316. end
  317. def test_exception_infinity
  318. _test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal("Infinity") }
  319. end
  320. def test_exception_underflow
  321. _test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do
  322. x = BigDecimal("0.1")
  323. 100.times do
  324. x *= x
  325. end
  326. end
  327. end
  328. def test_exception_overflow
  329. _test_mode(BigDecimal::EXCEPTION_OVERFLOW) do
  330. x = BigDecimal("10")
  331. 100.times do
  332. x *= x
  333. end
  334. end
  335. end
  336. def test_exception_zerodivide
  337. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  338. _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal("0") }
  339. _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal("0") }
  340. end
  341. def test_round_up
  342. n4 = BigDecimal("4") # n4 / 9 = 0.44444...
  343. n5 = BigDecimal("5") # n5 / 9 = 0.55555...
  344. n6 = BigDecimal("6") # n6 / 9 = 0.66666...
  345. m4, m5, m6 = -n4, -n5, -n6
  346. n2h = BigDecimal("2.5")
  347. n3h = BigDecimal("3.5")
  348. m2h, m3h = -n2h, -n3h
  349. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
  350. assert_operator(n4, :<, n4 / 9 * 9)
  351. assert_operator(n5, :<, n5 / 9 * 9)
  352. assert_operator(n6, :<, n6 / 9 * 9)
  353. assert_operator(m4, :>, m4 / 9 * 9)
  354. assert_operator(m5, :>, m5 / 9 * 9)
  355. assert_operator(m6, :>, m6 / 9 * 9)
  356. assert_equal(3, n2h.round)
  357. assert_equal(4, n3h.round)
  358. assert_equal(-3, m2h.round)
  359. assert_equal(-4, m3h.round)
  360. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
  361. assert_operator(n4, :>, n4 / 9 * 9)
  362. assert_operator(n5, :>, n5 / 9 * 9)
  363. assert_operator(n6, :>, n6 / 9 * 9)
  364. assert_operator(m4, :<, m4 / 9 * 9)
  365. assert_operator(m5, :<, m5 / 9 * 9)
  366. assert_operator(m6, :<, m6 / 9 * 9)
  367. assert_equal(2, n2h.round)
  368. assert_equal(3, n3h.round)
  369. assert_equal(-2, m2h.round)
  370. assert_equal(-3, m3h.round)
  371. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
  372. assert_operator(n4, :>, n4 / 9 * 9)
  373. assert_operator(n5, :<, n5 / 9 * 9)
  374. assert_operator(n6, :<, n6 / 9 * 9)
  375. assert_operator(m4, :<, m4 / 9 * 9)
  376. assert_operator(m5, :>, m5 / 9 * 9)
  377. assert_operator(m6, :>, m6 / 9 * 9)
  378. assert_equal(3, n2h.round)
  379. assert_equal(4, n3h.round)
  380. assert_equal(-3, m2h.round)
  381. assert_equal(-4, m3h.round)
  382. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
  383. assert_operator(n4, :>, n4 / 9 * 9)
  384. assert_operator(n5, :>, n5 / 9 * 9)
  385. assert_operator(n6, :<, n6 / 9 * 9)
  386. assert_operator(m4, :<, m4 / 9 * 9)
  387. assert_operator(m5, :<, m5 / 9 * 9)
  388. assert_operator(m6, :>, m6 / 9 * 9)
  389. assert_equal(2, n2h.round)
  390. assert_equal(3, n3h.round)
  391. assert_equal(-2, m2h.round)
  392. assert_equal(-3, m3h.round)
  393. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
  394. assert_operator(n4, :>, n4 / 9 * 9)
  395. assert_operator(n5, :<, n5 / 9 * 9)
  396. assert_operator(n6, :<, n6 / 9 * 9)
  397. assert_operator(m4, :<, m4 / 9 * 9)
  398. assert_operator(m5, :>, m5 / 9 * 9)
  399. assert_operator(m6, :>, m6 / 9 * 9)
  400. assert_equal(2, n2h.round)
  401. assert_equal(4, n3h.round)
  402. assert_equal(-2, m2h.round)
  403. assert_equal(-4, m3h.round)
  404. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
  405. assert_operator(n4, :<, n4 / 9 * 9)
  406. assert_operator(n5, :<, n5 / 9 * 9)
  407. assert_operator(n6, :<, n6 / 9 * 9)
  408. assert_operator(m4, :<, m4 / 9 * 9)
  409. assert_operator(m5, :<, m5 / 9 * 9)
  410. assert_operator(m6, :<, m6 / 9 * 9)
  411. assert_equal(3, n2h.round)
  412. assert_equal(4, n3h.round)
  413. assert_equal(-2, m2h.round)
  414. assert_equal(-3, m3h.round)
  415. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
  416. assert_operator(n4, :>, n4 / 9 * 9)
  417. assert_operator(n5, :>, n5 / 9 * 9)
  418. assert_operator(n6, :>, n6 / 9 * 9)
  419. assert_operator(m4, :>, m4 / 9 * 9)
  420. assert_operator(m5, :>, m5 / 9 * 9)
  421. assert_operator(m6, :>, m6 / 9 * 9)
  422. assert_equal(2, n2h.round)
  423. assert_equal(3, n3h.round)
  424. assert_equal(-3, m2h.round)
  425. assert_equal(-4, m3h.round)
  426. end
  427. def test_zero_p
  428. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  429. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  430. assert_equal(true, BigDecimal("0").zero?)
  431. assert_equal(true, BigDecimal("-0").zero?)
  432. assert_equal(false, BigDecimal("1").zero?)
  433. assert_equal(true, BigDecimal("0E200000000000000").zero?)
  434. assert_equal(false, BigDecimal("Infinity").zero?)
  435. assert_equal(false, BigDecimal("-Infinity").zero?)
  436. assert_equal(false, BigDecimal("NaN").zero?)
  437. end
  438. def test_nonzero_p
  439. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  440. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  441. assert_equal(nil, BigDecimal("0").nonzero?)
  442. assert_equal(nil, BigDecimal("-0").nonzero?)
  443. assert_equal(BigDecimal("1"), BigDecimal("1").nonzero?)
  444. assert_positive_infinite(BigDecimal("Infinity").nonzero?)
  445. assert_negative_infinite(BigDecimal("-Infinity").nonzero?)
  446. assert_nan(BigDecimal("NaN").nonzero?)
  447. end
  448. def test_double_fig
  449. assert_kind_of(Integer, BigDecimal.double_fig)
  450. end
  451. def test_cmp
  452. n1 = BigDecimal("1")
  453. n2 = BigDecimal("2")
  454. assert_equal( 0, n1 <=> n1)
  455. assert_equal( 1, n2 <=> n1)
  456. assert_equal(-1, n1 <=> n2)
  457. assert_operator(n1, :==, n1)
  458. assert_operator(n1, :!=, n2)
  459. assert_operator(n1, :<, n2)
  460. assert_operator(n1, :<=, n1)
  461. assert_operator(n1, :<=, n2)
  462. assert_operator(n2, :>, n1)
  463. assert_operator(n2, :>=, n1)
  464. assert_operator(n1, :>=, n1)
  465. assert_operator(BigDecimal("-0"), :==, BigDecimal("0"))
  466. assert_operator(BigDecimal("0"), :<, BigDecimal("1"))
  467. assert_operator(BigDecimal("1"), :>, BigDecimal("0"))
  468. assert_operator(BigDecimal("1"), :>, BigDecimal("-1"))
  469. assert_operator(BigDecimal("-1"), :<, BigDecimal("1"))
  470. assert_operator(BigDecimal((2**100).to_s), :>, BigDecimal("1"))
  471. assert_operator(BigDecimal("1"), :<, BigDecimal((2**100).to_s))
  472. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  473. inf = BigDecimal("Infinity")
  474. assert_operator(inf, :>, 1)
  475. assert_operator(1, :<, inf)
  476. assert_operator(BigDecimal("1E-1"), :==, 10**(-1), '#4825')
  477. assert_equal(0, BigDecimal("1E-1") <=> 10**(-1), '#4825')
  478. end
  479. def test_cmp_issue9192
  480. bug9192 = '[ruby-core:58756] [#9192]'
  481. operators = { :== => :==, :< => :>, :> => :<, :<= => :>=, :>= => :<= }
  482. 5.upto(8) do |i|
  483. s = "706.0#{i}"
  484. d = BigDecimal(s)
  485. f = s.to_f
  486. operators.each do |op, inv|
  487. assert_equal(d.send(op, f), f.send(inv, d),
  488. "(BigDecimal(#{s.inspect}) #{op} #{s}) and (#{s} #{inv} BigDecimal(#{s.inspect})) is different #{bug9192}")
  489. end
  490. end
  491. end
  492. def test_cmp_nan
  493. n1 = BigDecimal("1")
  494. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  495. assert_equal(nil, BigDecimal("NaN") <=> n1)
  496. assert_equal(false, BigDecimal("NaN") > n1)
  497. assert_equal(nil, BigDecimal("NaN") <=> BigDecimal("NaN"))
  498. assert_equal(false, BigDecimal("NaN") == BigDecimal("NaN"))
  499. end
  500. def test_cmp_failing_coercion
  501. n1 = BigDecimal("1")
  502. assert_equal(nil, n1 <=> nil)
  503. assert_raise(ArgumentError){n1 > nil}
  504. end
  505. def test_cmp_coerce
  506. n1 = BigDecimal("1")
  507. n2 = BigDecimal("2")
  508. o1 = Object.new; def o1.coerce(x); [x, BigDecimal("1")]; end
  509. o2 = Object.new; def o2.coerce(x); [x, BigDecimal("2")]; end
  510. assert_equal( 0, n1 <=> o1)
  511. assert_equal( 1, n2 <=> o1)
  512. assert_equal(-1, n1 <=> o2)
  513. assert_operator(n1, :==, o1)
  514. assert_operator(n1, :!=, o2)
  515. assert_operator(n1, :<, o2)
  516. assert_operator(n1, :<=, o1)
  517. assert_operator(n1, :<=, o2)
  518. assert_operator(n2, :>, o1)
  519. assert_operator(n2, :>=, o1)
  520. assert_operator(n1, :>=, 1)
  521. bug10109 = '[ruby-core:64190]'
  522. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  523. assert_operator(BigDecimal(0), :<, Float::INFINITY, bug10109)
  524. assert_operator(Float::INFINITY, :>, BigDecimal(0), bug10109)
  525. end
  526. def test_cmp_bignum
  527. assert_operator(BigDecimal((2**100).to_s), :==, 2**100)
  528. end
  529. def test_cmp_data
  530. d = Time.now; def d.coerce(x); [x, x]; end
  531. assert_operator(BigDecimal((2**100).to_s), :==, d)
  532. end
  533. def test_precs
  534. a = BigDecimal("1").precs
  535. assert_instance_of(Array, a)
  536. assert_equal(2, a.size)
  537. assert_kind_of(Integer, a[0])
  538. assert_kind_of(Integer, a[1])
  539. end
  540. def test_hash
  541. a = []
  542. b = BigDecimal("1")
  543. 10.times { a << b *= 10 }
  544. h = {}
  545. a.each_with_index {|x, i| h[x] = i }
  546. a.each_with_index do |x, i|
  547. assert_equal(i, h[x])
  548. end
  549. end
  550. def test_marshal
  551. s = Marshal.dump(BigDecimal("1", 1))
  552. assert_equal(BigDecimal("1", 1), Marshal.load(s))
  553. # corrupt data
  554. s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") }
  555. assert_raise(TypeError) { Marshal.load(s) }
  556. end
  557. def test_finite_infinite_nan
  558. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  559. BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
  560. x = BigDecimal("0")
  561. assert_equal(true, x.finite?)
  562. assert_equal(nil, x.infinite?)
  563. assert_equal(false, x.nan?)
  564. y = 1 / x
  565. assert_equal(false, y.finite?)
  566. assert_equal(1, y.infinite?)
  567. assert_equal(false, y.nan?)
  568. y = -1 / x
  569. assert_equal(false, y.finite?)
  570. assert_equal(-1, y.infinite?)
  571. assert_equal(false, y.nan?)
  572. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  573. y = 0 / x
  574. assert_equal(false, y.finite?)
  575. assert_equal(nil, y.infinite?)
  576. assert_equal(true, y.nan?)
  577. end
  578. def test_to_i
  579. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  580. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  581. x = BigDecimal("0")
  582. assert_kind_of(Integer, x.to_i)
  583. assert_equal(0, x.to_i)
  584. assert_raise(FloatDomainError){( 1 / x).to_i}
  585. assert_raise(FloatDomainError){(-1 / x).to_i}
  586. assert_raise(FloatDomainError) {( 0 / x).to_i}
  587. x = BigDecimal("1")
  588. assert_equal(1, x.to_i)
  589. x = BigDecimal((2**100).to_s)
  590. assert_equal(2**100, x.to_i)
  591. end
  592. def test_to_f
  593. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  594. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  595. BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
  596. x = BigDecimal("0")
  597. assert_instance_of(Float, x.to_f)
  598. assert_equal(0.0, x.to_f)
  599. assert_equal( 1.0 / 0.0, ( 1 / x).to_f)
  600. assert_equal(-1.0 / 0.0, (-1 / x).to_f)
  601. assert_nan(( 0 / x).to_f)
  602. x = BigDecimal("1")
  603. assert_equal(1.0, x.to_f)
  604. x = BigDecimal((2**100).to_s)
  605. assert_equal((2**100).to_f, x.to_f)
  606. x = BigDecimal("1" + "0" * 10000)
  607. assert_equal(0, BigDecimal("-0").to_f)
  608. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
  609. assert_raise(FloatDomainError) { x.to_f }
  610. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  611. assert_kind_of(Float, x .to_f)
  612. assert_kind_of(Float, (-x).to_f)
  613. bug6944 = '[ruby-core:47342]'
  614. BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
  615. x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
  616. assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
  617. x = "-#{x}"
  618. assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
  619. x = "1e#{Float::MIN_10_EXP - Float::DIG}"
  620. assert_nothing_raised(FloatDomainError, x) {
  621. assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
  622. }
  623. x = "-#{x}"
  624. assert_nothing_raised(FloatDomainError, x) {
  625. assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
  626. }
  627. BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false)
  628. x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
  629. assert_equal( 0.0, BigDecimal(x).to_f, x)
  630. x = "-#{x}"
  631. assert_equal(-0.0, BigDecimal(x).to_f, x)
  632. x = "1e#{Float::MIN_10_EXP - Float::DIG}"
  633. assert_nothing_raised(FloatDomainError, x) {
  634. assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
  635. }
  636. x = "-#{x}"
  637. assert_nothing_raised(FloatDomainError, x) {
  638. assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
  639. }
  640. assert_equal( 0.0, BigDecimal( '9e-325').to_f)
  641. assert_equal( 0.0, BigDecimal( '10e-325').to_f)
  642. assert_equal(-0.0, BigDecimal( '-9e-325').to_f)
  643. assert_equal(-0.0, BigDecimal('-10e-325').to_f)
  644. end
  645. def test_to_r
  646. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  647. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  648. x = BigDecimal("0")
  649. assert_kind_of(Rational, x.to_r)
  650. assert_equal(0, x.to_r)
  651. assert_raise(FloatDomainError) {( 1 / x).to_r}
  652. assert_raise(FloatDomainError) {(-1 / x).to_r}
  653. assert_raise(FloatDomainError) {( 0 / x).to_r}
  654. assert_equal(1, BigDecimal("1").to_r)
  655. assert_equal(Rational(3, 2), BigDecimal("1.5").to_r)
  656. assert_equal((2**100).to_r, BigDecimal((2**100).to_s).to_r)
  657. end
  658. def test_coerce
  659. a, b = BigDecimal("1").coerce(1.0)
  660. assert_instance_of(BigDecimal, a)
  661. assert_instance_of(BigDecimal, b)
  662. assert_equal(2, 1 + BigDecimal("1"), '[ruby-core:25697]')
  663. a, b = BigDecimal("1").coerce(1.quo(10))
  664. assert_equal(BigDecimal("0.1"), a, '[ruby-core:34318]')
  665. a, b = BigDecimal("0.11111").coerce(1.quo(3))
  666. assert_equal(BigDecimal("0." + "3"*a.precs[0]), a)
  667. assert_nothing_raised(TypeError, '#7176') do
  668. BigDecimal('1') + Rational(1)
  669. end
  670. end
  671. def test_uplus
  672. x = BigDecimal("1")
  673. assert_equal(x, x.send(:+@))
  674. end
  675. def test_neg
  676. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  677. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  678. assert_equal(BigDecimal("-1"), BigDecimal("1").send(:-@))
  679. assert_equal(BigDecimal("-0"), BigDecimal("0").send(:-@))
  680. assert_equal(BigDecimal("0"), BigDecimal("-0").send(:-@))
  681. assert_equal(BigDecimal("-Infinity"), BigDecimal("Infinity").send(:-@))
  682. assert_equal(BigDecimal("Infinity"), BigDecimal("-Infinity").send(:-@))
  683. assert_equal(true, BigDecimal("NaN").send(:-@).nan?)
  684. end
  685. def test_add
  686. x = BigDecimal("1")
  687. assert_equal(BigDecimal("2"), x + x)
  688. assert_equal(1, BigDecimal("0") + 1)
  689. assert_equal(1, x + 0)
  690. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") + 0).sign)
  691. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("-0") + 0).sign)
  692. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") + BigDecimal("-0")).sign)
  693. x = BigDecimal((2**100).to_s)
  694. assert_equal(BigDecimal((2**100+1).to_s), x + 1)
  695. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  696. inf = BigDecimal("Infinity")
  697. neginf = BigDecimal("-Infinity")
  698. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  699. assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf + inf }
  700. assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf + neginf }
  701. end
  702. def test_sub
  703. x = BigDecimal("1")
  704. assert_equal(BigDecimal("0"), x - x)
  705. assert_equal(-1, BigDecimal("0") - 1)
  706. assert_equal(1, x - 0)
  707. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") - 0).sign)
  708. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") - 0).sign)
  709. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("-0") - BigDecimal("-0")).sign)
  710. x = BigDecimal((2**100).to_s)
  711. assert_equal(BigDecimal((2**100-1).to_s), x - 1)
  712. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  713. inf = BigDecimal("Infinity")
  714. neginf = BigDecimal("-Infinity")
  715. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  716. assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf - neginf }
  717. assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf - inf }
  718. end
  719. def test_sub_with_float
  720. assert_kind_of(BigDecimal, BigDecimal("3") - 1.0)
  721. end
  722. def test_sub_with_rational
  723. assert_kind_of(BigDecimal, BigDecimal("3") - 1.quo(3))
  724. end
  725. def test_mult
  726. x = BigDecimal((2**100).to_s)
  727. assert_equal(BigDecimal((2**100 * 3).to_s), (x * 3).to_i)
  728. assert_equal(x, (x * 1).to_i)
  729. assert_equal(x, (BigDecimal("1") * x).to_i)
  730. assert_equal(BigDecimal((2**200).to_s), (x * x).to_i)
  731. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  732. inf = BigDecimal("Infinity")
  733. neginf = BigDecimal("-Infinity")
  734. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  735. assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf * inf }
  736. assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf * inf }
  737. end
  738. def test_mult_with_float
  739. assert_kind_of(BigDecimal, BigDecimal("3") * 1.5)
  740. end
  741. def test_mult_with_rational
  742. assert_kind_of(BigDecimal, BigDecimal("3") * 1.quo(3))
  743. end
  744. def test_mult_with_nil
  745. assert_raise(TypeError) {
  746. BigDecimal('1.1') * nil
  747. }
  748. end
  749. def test_div
  750. x = BigDecimal((2**100).to_s)
  751. assert_equal(BigDecimal((2**100 / 3).to_s), (x / 3).to_i)
  752. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") / 1).sign)
  753. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") / 1).sign)
  754. assert_equal(2, BigDecimal("2") / 1)
  755. assert_equal(-2, BigDecimal("2") / -1)
  756. assert_equal(BigDecimal('1486.868686869'), BigDecimal('1472.0') / BigDecimal('0.99'), '[ruby-core:59365] [#9316]')
  757. assert_equal(4.124045235, BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0')), '[#9305]')
  758. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  759. assert_positive_zero(BigDecimal("1.0") / BigDecimal("Infinity"))
  760. assert_negative_zero(BigDecimal("-1.0") / BigDecimal("Infinity"))
  761. assert_negative_zero(BigDecimal("1.0") / BigDecimal("-Infinity"))
  762. assert_positive_zero(BigDecimal("-1.0") / BigDecimal("-Infinity"))
  763. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
  764. BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
  765. assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { BigDecimal("1") / 0 }
  766. assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { BigDecimal("-1") / 0 }
  767. end
  768. def test_div_with_float
  769. assert_kind_of(BigDecimal, BigDecimal("3") / 1.5)
  770. end
  771. def test_div_with_rational
  772. assert_kind_of(BigDecimal, BigDecimal("3") / 1.quo(3))
  773. end
  774. def test_mod
  775. x = BigDecimal((2**100).to_s)
  776. assert_equal(1, x % 3)
  777. assert_equal(2, (-x) % 3)
  778. assert_equal(-2, x % -3)
  779. assert_equal(-1, (-x) % -3)
  780. end
  781. def test_mod_with_float
  782. assert_kind_of(BigDecimal, BigDecimal("3") % 1.5)
  783. end
  784. def test_mod_with_rational
  785. assert_kind_of(BigDecimal, BigDecimal("3") % 1.quo(3))
  786. end
  787. def test_remainder
  788. x = BigDecimal((2**100).to_s)
  789. assert_equal(1, x.remainder(3))
  790. assert_equal(-1, (-x).remainder(3))
  791. assert_equal(1, x.remainder(-3))
  792. assert_equal(-1, (-x).remainder(-3))
  793. end
  794. def test_remainder_with_float
  795. assert_kind_of(BigDecimal, BigDecimal("3").remainder(1.5))
  796. end
  797. def test_remainder_with_rational
  798. assert_kind_of(BigDecimal, BigDecimal("3").remainder(1.quo(3)))
  799. end
  800. def test_divmod
  801. x = BigDecimal((2**100).to_s)
  802. assert_equal([(x / 3).floor, 1], x.divmod(3))
  803. assert_equal([(-x / 3).floor, 2], (-x).divmod(3))
  804. assert_equal([0, 0], BigDecimal("0").divmod(2))
  805. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  806. assert_raise(ZeroDivisionError){BigDecimal("0").divmod(0)}
  807. end
  808. def test_add_bigdecimal
  809. x = BigDecimal((2**100).to_s)
  810. assert_equal(3000000000000000000000000000000, x.add(x, 1))
  811. assert_equal(2500000000000000000000000000000, x.add(x, 2))
  812. assert_equal(2540000000000000000000000000000, x.add(x, 3))
  813. end
  814. def test_sub_bigdecimal
  815. x = BigDecimal((2**100).to_s)
  816. assert_equal(1000000000000000000000000000000, x.sub(1, 1))
  817. assert_equal(1300000000000000000000000000000, x.sub(1, 2))
  818. assert_equal(1270000000000000000000000000000, x.sub(1, 3))
  819. end
  820. def test_mult_bigdecimal
  821. x = BigDecimal((2**100).to_s)
  822. assert_equal(4000000000000000000000000000000, x.mult(3, 1))
  823. assert_equal(3800000000000000000000000000000, x.mult(3, 2))
  824. assert_equal(3800000000000000000000000000000, x.mult(3, 3))
  825. end
  826. def test_div_bigdecimal
  827. x = BigDecimal((2**100).to_s)
  828. assert_equal(422550200076076467165567735125, x.div(3))
  829. assert_equal(400000000000000000000000000000, x.div(3, 1))
  830. assert_equal(420000000000000000000000000000, x.div(3, 2))
  831. assert_equal(423000000000000000000000000000, x.div(3, 3))
  832. BigDecimal.save_exception_mode do
  833. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  834. assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity")))
  835. end
  836. end
  837. def test_abs_bigdecimal
  838. x = BigDecimal((2**100).to_s)
  839. assert_equal(1267650600228229401496703205376, x.abs)
  840. x = BigDecimal("-" + (2**100).to_s)
  841. assert_equal(1267650600228229401496703205376, x.abs)
  842. x = BigDecimal("0")
  843. assert_equal(0, x.abs)
  844. x = BigDecimal("-0")
  845. assert_equal(0, x.abs)
  846. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  847. x = BigDecimal("Infinity")
  848. assert_equal(BigDecimal("Infinity"), x.abs)
  849. x = BigDecimal("-Infinity")
  850. assert_equal(BigDecimal("Infinity"), x.abs)
  851. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  852. x = BigDecimal("NaN")
  853. assert_nan(x.abs)
  854. end
  855. def test_sqrt_bigdecimal
  856. x = BigDecimal("0.09")
  857. assert_in_delta(0.3, x.sqrt(1), 0.001)
  858. x = BigDecimal((2**100).to_s)
  859. y = BigDecimal("1125899906842624")
  860. e = y.exponent
  861. assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}"))
  862. assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}"))
  863. assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}"))
  864. x = BigDecimal("-" + (2**100).to_s)
  865. assert_raise_with_message(FloatDomainError, "sqrt of negative value") { x.sqrt(1) }
  866. x = BigDecimal((2**200).to_s)
  867. assert_equal(2**100, x.sqrt(1))
  868. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  869. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  870. assert_raise_with_message(FloatDomainError, "sqrt of 'NaN'(Not a Number)") { BigDecimal("NaN").sqrt(1) }
  871. assert_raise_with_message(FloatDomainError, "sqrt of negative value") { BigDecimal("-Infinity").sqrt(1) }
  872. assert_equal(0, BigDecimal("0").sqrt(1))
  873. assert_equal(0, BigDecimal("-0").sqrt(1))
  874. assert_equal(1, BigDecimal("1").sqrt(1))
  875. assert_positive_infinite(BigDecimal("Infinity").sqrt(1))
  876. end
  877. def test_sqrt_5266
  878. x = BigDecimal('2' + '0'*100)
  879. assert_equal('0.14142135623730950488016887242096980785696718753769480731',
  880. x.sqrt(56).to_s(56).split(' ')[0])
  881. assert_equal('0.1414213562373095048801688724209698078569671875376948073',
  882. x.sqrt(55).to_s(55).split(' ')[0])
  883. x = BigDecimal('2' + '0'*200)
  884. assert_equal('0.14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462',
  885. x.sqrt(110).to_s(110).split(' ')[0])
  886. assert_equal('0.1414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846',
  887. x.sqrt(109).to_s(109).split(' ')[0])
  888. end
  889. def test_fix
  890. x = BigDecimal("1.1")
  891. assert_equal(1, x.fix)
  892. assert_kind_of(BigDecimal, x.fix)
  893. end
  894. def test_frac
  895. x = BigDecimal("1.1")
  896. assert_equal(0.1, x.frac)
  897. assert_equal(0.1, BigDecimal("0.1").frac)
  898. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  899. assert_nan(BigDecimal("NaN").frac)
  900. end
  901. def test_round
  902. assert_equal(3, BigDecimal("3.14159").round)
  903. assert_equal(9, BigDecimal("8.7").round)
  904. assert_equal(3.142, BigDecimal("3.14159").round(3))
  905. assert_equal(13300.0, BigDecimal("13345.234").round(-2))
  906. x = BigDecimal("111.111")
  907. assert_equal(111 , x.round)
  908. assert_equal(111.1 , x.round(1))
  909. assert_equal(111.11 , x.round(2))
  910. assert_equal(111.111, x.round(3))
  911. assert_equal(111.111, x.round(4))
  912. assert_equal(110 , x.round(-1))
  913. assert_equal(100 , x.round(-2))
  914. assert_equal( 0 , x.round(-3))
  915. assert_equal( 0 , x.round(-4))
  916. x = BigDecimal("2.5")
  917. assert_equal(3, x.round(0, BigDecimal::ROUND_UP))
  918. assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN))
  919. assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP))
  920. assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
  921. assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
  922. assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING))
  923. assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR))
  924. assert_raise(ArgumentError) { x.round(0, 256) }
  925. x = BigDecimal("-2.5")
  926. assert_equal(-3, x.round(0, BigDecimal::ROUND_UP))
  927. assert_equal(-2, x.round(0, BigDecimal::ROUND_DOWN))
  928. assert_equal(-3, x.round(0, BigDecimal::ROUND_HALF_UP))
  929. assert_equal(-2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
  930. assert_equal(-2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
  931. assert_equal(-2, x.round(0, BigDecimal::ROUND_CEILING))
  932. assert_equal(-3, x.round(0, BigDecimal::ROUND_FLOOR))
  933. ROUNDING_MODE_MAP.each do |const, sym|
  934. assert_equal(x.round(0, const), x.round(0, sym))
  935. end
  936. bug3803 = '[ruby-core:32136]'
  937. 15.times do |n|
  938. x = BigDecimal("5#{'0'*n}1")
  939. assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_DOWN), bug3803)
  940. assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_EVEN), bug3803)
  941. x = BigDecimal("0.5#{'0'*n}1")
  942. assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
  943. assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
  944. x = BigDecimal("-0.5#{'0'*n}1")
  945. assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
  946. assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
  947. end
  948. end
  949. def test_round_half_even
  950. assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :even))
  951. assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :even))
  952. assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :even))
  953. assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :even))
  954. assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :even))
  955. assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :even))
  956. assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :even))
  957. assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :even))
  958. assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :even))
  959. assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :even))
  960. assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :even))
  961. assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :even))
  962. assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :even))
  963. assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :even))
  964. end
  965. def test_round_half_up
  966. assert_equal(BigDecimal('13.0'), BigDecimal('12.5').round(half: :up))
  967. assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :up))
  968. assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :up))
  969. assert_equal(BigDecimal('2.3'), BigDecimal('2.25').round(1, half: :up))
  970. assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :up))
  971. assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :up))
  972. assert_equal(BigDecimal('-2.3'), BigDecimal('-2.25').round(1, half: :up))
  973. assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :up))
  974. assert_equal(BigDecimal('7.1365'), BigDecimal('7.13645').round(4, half: :up))
  975. assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :up))
  976. assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :up))
  977. assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.13645').round(4, half: :up))
  978. assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :up))
  979. assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :up))
  980. end
  981. def test_round_half_down
  982. assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :down))
  983. assert_equal(BigDecimal('13.0'), BigDecimal('13.5').round(half: :down))
  984. assert_equal(BigDecimal('2.1'), BigDecimal('2.15').round(1, half: :down))
  985. assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :down))
  986. assert_equal(BigDecimal('2.3'), BigDecimal('2.35').round(1, half: :down))
  987. assert_equal(BigDecimal('-2.1'), BigDecimal('-2.15').round(1, half: :down))
  988. assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :down))
  989. assert_equal(BigDecimal('-2.3'), BigDecimal('-2.35').round(1, half: :down))
  990. assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :down))
  991. assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :down))
  992. assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :down))
  993. assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :down))
  994. assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :down))
  995. assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :down))
  996. end
  997. def test_round_half_nil
  998. x = BigDecimal("2.5")
  999. BigDecimal.save_rounding_mode do
  1000. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
  1001. assert_equal(3, x.round(0, half: nil))
  1002. end
  1003. BigDecimal.save_rounding_mode do
  1004. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
  1005. assert_equal(2, x.round(0, half: nil))
  1006. end
  1007. BigDecimal.save_rounding_mode do
  1008. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
  1009. assert_equal(3, x.round(0, half: nil))
  1010. end
  1011. BigDecimal.save_rounding_mode do
  1012. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
  1013. assert_equal(2, x.round(0, half: nil))
  1014. end
  1015. BigDecimal.save_rounding_mode do
  1016. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
  1017. assert_equal(2, x.round(0, half: nil))
  1018. end
  1019. BigDecimal.save_rounding_mode do
  1020. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
  1021. assert_equal(3, x.round(0, half: nil))
  1022. end
  1023. BigDecimal.save_rounding_mode do
  1024. BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
  1025. assert_equal(2, x.round(0, half: nil))
  1026. end
  1027. end
  1028. def test_round_half_invalid_option
  1029. assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('12.5').round(half: :invalid) }
  1030. assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('2.15').round(1, half: :invalid) }
  1031. end
  1032. def test_truncate
  1033. assert_equal(3, BigDecimal("3.14159").truncate)
  1034. assert_equal(8, BigDecimal("8.7").truncate)
  1035. assert_equal(3.141, BigDecimal("3.14159").truncate(3))
  1036. assert_equal(13300.0, BigDecimal("13345.234").truncate(-2))
  1037. assert_equal(-3, BigDecimal("-3.14159").truncate)
  1038. assert_equal(-8, BigDecimal("-8.7").truncate)
  1039. assert_equal(-3.141, BigDecimal("-3.14159").truncate(3))
  1040. assert_equal(-13300.0, BigDecimal("-13345.234").truncate(-2))
  1041. end
  1042. def test_floor
  1043. assert_equal(3, BigDecimal("3.14159").floor)
  1044. assert_equal(-10, BigDecimal("-9.1").floor)
  1045. assert_equal(3.141, BigDecimal("3.14159").floor(3))
  1046. assert_equal(13300.0, BigDecimal("13345.234").floor(-2))
  1047. end
  1048. def test_ceil
  1049. assert_equal(4, BigDecimal("3.14159").ceil)
  1050. assert_equal(-9, BigDecimal("-9.1").ceil)
  1051. assert_equal(3.142, BigDecimal("3.14159").ceil(3))
  1052. assert_equal(13400.0, BigDecimal("13345.234").ceil(-2))
  1053. end
  1054. def test_to_s
  1055. assert_equal('-123.45678 90123 45678 9', BigDecimal('-123.45678901234567890').to_s('5F'))
  1056. assert_equal('+123.45678901 23456789', BigDecimal('123.45678901234567890').to_s('+8F'))
  1057. assert_equal(' 123.4567890123456789', BigDecimal('123.45678901234567890').to_s(' F'))
  1058. assert_equal('0.1234567890123456789e3', BigDecimal('123.45678901234567890').to_s)
  1059. assert_equal('0.12345 67890 12345 6789e3', BigDecimal('123.45678901234567890').to_s(5))
  1060. end
  1061. def test_split
  1062. x = BigDecimal('-123.45678901234567890')
  1063. assert_equal([-1, "1234567890123456789", 10, 3], x.split)
  1064. assert_equal([1, "0", 10, 0], BigDecimal("0").split)
  1065. assert_equal([-1, "0", 10, 0], BigDecimal("-0").split)
  1066. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1067. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1068. assert_equal([0, "NaN", 10, 0], BigDecimal("NaN").split)
  1069. assert_equal([1, "Infinity", 10, 0], BigDecimal("Infinity").split)
  1070. assert_equal([-1, "Infinity", 10, 0], BigDecimal("-Infinity").split)
  1071. end
  1072. def test_exponent
  1073. x = BigDecimal('-123.45678901234567890')
  1074. assert_equal(3, x.exponent)
  1075. end
  1076. def test_inspect
  1077. assert_equal("0.123456789012e0", BigDecimal("0.123456789012").inspect)
  1078. assert_equal("0.123456789012e4", BigDecimal("1234.56789012").inspect)
  1079. assert_equal("0.123456789012e-4", BigDecimal("0.0000123456789012").inspect)
  1080. end
  1081. def test_power
  1082. assert_nothing_raised(TypeError, '[ruby-core:47632]') do
  1083. 1000.times { BigDecimal('1001.10')**0.75 }
  1084. end
  1085. end
  1086. def test_power_with_nil
  1087. assert_raise(TypeError) do
  1088. BigDecimal(3) ** nil
  1089. end
  1090. end
  1091. def test_power_of_nan
  1092. BigDecimal.save_exception_mode do
  1093. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1094. assert_nan(BigDecimal::NAN ** 0)
  1095. assert_nan(BigDecimal::NAN ** 1)
  1096. assert_nan(BigDecimal::NAN ** 42)
  1097. assert_nan(BigDecimal::NAN ** -42)
  1098. assert_nan(BigDecimal::NAN ** 42.0)
  1099. assert_nan(BigDecimal::NAN ** -42.0)
  1100. assert_nan(BigDecimal::NAN ** BigDecimal(42))
  1101. assert_nan(BigDecimal::NAN ** BigDecimal(-42))
  1102. assert_nan(BigDecimal::NAN ** BigDecimal::INFINITY)
  1103. BigDecimal.save_exception_mode do
  1104. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1105. assert_nan(BigDecimal::NAN ** (-BigDecimal::INFINITY))
  1106. end
  1107. end
  1108. end
  1109. def test_power_with_Bignum
  1110. BigDecimal.save_exception_mode do
  1111. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1112. assert_equal(0, BigDecimal(0) ** (2**100))
  1113. assert_positive_infinite(BigDecimal(0) ** -(2**100))
  1114. assert_positive_infinite((-BigDecimal(0)) ** -(2**100))
  1115. assert_negative_infinite((-BigDecimal(0)) ** -(2**100 + 1))
  1116. assert_equal(1, BigDecimal(1) ** (2**100))
  1117. assert_positive_infinite(BigDecimal(3) ** (2**100))
  1118. assert_positive_zero(BigDecimal(3) ** (-2**100))
  1119. assert_negative_infinite(BigDecimal(-3) ** (2**100))
  1120. assert_positive_infinite(BigDecimal(-3) ** (2**100 + 1))
  1121. assert_negative_zero(BigDecimal(-3) ** (-2**100))
  1122. assert_positive_zero(BigDecimal(-3) ** (-2**100 - 1))
  1123. assert_positive_zero(BigDecimal(0.5, Float::DIG) ** (2**100))
  1124. assert_positive_infinite(BigDecimal(0.5, Float::DIG) ** (-2**100))
  1125. assert_negative_zero(BigDecimal(-0.5, Float::DIG) ** (2**100))
  1126. assert_positive_zero(BigDecimal(-0.5, Float::DIG) ** (2**100 - 1))
  1127. assert_negative_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100))
  1128. assert_positive_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100 - 1))
  1129. end
  1130. end
  1131. def test_power_with_BigDecimal
  1132. assert_nothing_raised do
  1133. assert_in_delta(3 ** 3, BigDecimal(3) ** BigDecimal(3))
  1134. end
  1135. end
  1136. def test_power_of_finite_with_zero
  1137. x = BigDecimal(1)
  1138. assert_equal(1, x ** 0)
  1139. assert_equal(1, x ** 0.quo(1))
  1140. assert_equal(1, x ** 0.0)
  1141. assert_equal(1, x ** BigDecimal(0))
  1142. x = BigDecimal(42)
  1143. assert_equal(1, x ** 0)
  1144. assert_equal(1, x ** 0.quo(1))
  1145. assert_equal(1, x ** 0.0)
  1146. assert_equal(1, x ** BigDecimal(0))
  1147. x = BigDecimal(-42)
  1148. assert_equal(1, x ** 0)
  1149. assert_equal(1, x ** 0.quo(1))
  1150. assert_equal(1, x ** 0.0)
  1151. assert_equal(1, x ** BigDecimal(0))
  1152. end
  1153. def test_power_of_three
  1154. x = BigDecimal(3)
  1155. assert_equal(81, x ** 4)
  1156. assert_equal(1.quo(81), x ** -4)
  1157. assert_in_delta(1.0/81, x ** -4)
  1158. end
  1159. def test_power_of_zero
  1160. zero = BigDecimal(0)
  1161. assert_equal(0, zero ** 4)
  1162. assert_equal(0, zero ** 4.quo(1))
  1163. assert_equal(0, zero ** 4.0)
  1164. assert_equal(0, zero ** BigDecimal(4))
  1165. assert_equal(1, zero ** 0)
  1166. assert_equal(1, zero ** 0.quo(1))
  1167. assert_equal(1, zero ** 0.0)
  1168. assert_equal(1, zero ** BigDecimal(0))
  1169. BigDecimal.save_exception_mode do
  1170. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1171. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1172. assert_positive_infinite(zero ** -1)
  1173. assert_positive_infinite(zero ** -1.quo(1))
  1174. assert_positive_infinite(zero ** -1.0)
  1175. assert_positive_infinite(zero ** BigDecimal(-1))
  1176. m_zero = BigDecimal("-0")
  1177. assert_negative_infinite(m_zero ** -1)
  1178. assert_negative_infinite(m_zero ** -1.quo(1))
  1179. assert_negative_infinite(m_zero ** -1.0)
  1180. assert_negative_infinite(m_zero ** BigDecimal(-1))
  1181. assert_positive_infinite(m_zero ** -2)
  1182. assert_positive_infinite(m_zero ** -2.quo(1))
  1183. assert_positive_infinite(m_zero ** -2.0)
  1184. assert_positive_infinite(m_zero ** BigDecimal(-2))
  1185. end
  1186. end
  1187. def test_power_of_positive_infinity
  1188. BigDecimal.save_exception_mode do
  1189. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1190. assert_positive_infinite(BigDecimal::INFINITY ** 3)
  1191. assert_positive_infinite(BigDecimal::INFINITY ** 3.quo(1))
  1192. assert_positive_infinite(BigDecimal::INFINITY ** 3.0)
  1193. assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(3))
  1194. assert_positive_infinite(BigDecimal::INFINITY ** 2)
  1195. assert_positive_infinite(BigDecimal::INFINITY ** 2.quo(1))
  1196. assert_positive_infinite(BigDecimal::INFINITY ** 2.0)
  1197. assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(2))
  1198. assert_positive_infinite(BigDecimal::INFINITY ** 1)
  1199. assert_positive_infinite(BigDecimal::INFINITY ** 1.quo(1))
  1200. assert_positive_infinite(BigDecimal::INFINITY ** 1.0)
  1201. assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(1))
  1202. assert_equal(1, BigDecimal::INFINITY ** 0)
  1203. assert_equal(1, BigDecimal::INFINITY ** 0.quo(1))
  1204. assert_equal(1, BigDecimal::INFINITY ** 0.0)
  1205. assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0))
  1206. assert_positive_zero(BigDecimal::INFINITY ** -1)
  1207. assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1))
  1208. assert_positive_zero(BigDecimal::INFINITY ** -1.0)
  1209. assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1))
  1210. assert_positive_zero(BigDecimal::INFINITY ** -2)
  1211. assert_positive_zero(BigDecimal::INFINITY ** -2.0)
  1212. assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2))
  1213. end
  1214. end
  1215. def test_power_of_negative_infinity
  1216. BigDecimal.save_exception_mode do
  1217. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1218. assert_negative_infinite((-BigDecimal::INFINITY) ** 3)
  1219. assert_negative_infinite((-BigDecimal::INFINITY) ** 3.quo(1))
  1220. assert_negative_infinite((-BigDecimal::INFINITY) ** 3.0)
  1221. assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(3))
  1222. assert_positive_infinite((-BigDecimal::INFINITY) ** 2)
  1223. assert_positive_infinite((-BigDecimal::INFINITY) ** 2.quo(1))
  1224. assert_positive_infinite((-BigDecimal::INFINITY) ** 2.0)
  1225. assert_positive_infinite((-BigDecimal::INFINITY) ** BigDecimal(2))
  1226. assert_negative_infinite((-BigDecimal::INFINITY) ** 1)
  1227. assert_negative_infinite((-BigDecimal::INFINITY) ** 1.quo(1))
  1228. assert_negative_infinite((-BigDecimal::INFINITY) ** 1.0)
  1229. assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(1))
  1230. assert_equal(1, (-BigDecimal::INFINITY) ** 0)
  1231. assert_equal(1, (-BigDecimal::INFINITY) ** 0.quo(1))
  1232. assert_equal(1, (-BigDecimal::INFINITY) ** 0.0)
  1233. assert_equal(1, (-BigDecimal::INFINITY) ** BigDecimal(0))
  1234. assert_negative_zero((-BigDecimal::INFINITY) ** -1)
  1235. assert_negative_zero((-BigDecimal::INFINITY) ** -1.quo(1))
  1236. assert_negative_zero((-BigDecimal::INFINITY) ** -1.0)
  1237. assert_negative_zero((-BigDecimal::INFINITY) ** BigDecimal(-1))
  1238. assert_positive_zero((-BigDecimal::INFINITY) ** -2)
  1239. assert_positive_zero((-BigDecimal::INFINITY) ** -2.quo(1))
  1240. assert_positive_zero((-BigDecimal::INFINITY) ** -2.0)
  1241. assert_positive_zero((-BigDecimal::INFINITY) ** BigDecimal(-2))
  1242. end
  1243. end
  1244. def test_power_without_prec
  1245. pi = BigDecimal("3.14159265358979323846264338327950288419716939937511")
  1246. e = BigDecimal("2.71828182845904523536028747135266249775724709369996")
  1247. pow = BigDecimal("22.4591577183610454734271522045437350275893151339967843873233068")
  1248. assert_equal(pow, pi.power(e))
  1249. end
  1250. def test_power_with_prec
  1251. pi = BigDecimal("3.14159265358979323846264338327950288419716939937511")
  1252. e = BigDecimal("2.71828182845904523536028747135266249775724709369996")
  1253. pow = BigDecimal("22.459157718361045473")
  1254. assert_equal(pow, pi.power(e, 20))
  1255. b = BigDecimal('1.034482758620689655172413793103448275862068965517241379310344827586206896551724')
  1256. assert_equal(BigDecimal('0.114523E1'), b.power(4, 5), '[Bug #8818] [ruby-core:56802]')
  1257. end
  1258. def test_limit
  1259. BigDecimal.limit(1)
  1260. x = BigDecimal("3")
  1261. assert_equal(90, x ** 4) # OK? must it be 80?
  1262. # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ???
  1263. assert_raise(ArgumentError) { BigDecimal.limit(-1) }
  1264. bug7458 = '[ruby-core:50269] [#7458]'
  1265. one = BigDecimal('1')
  1266. epsilon = BigDecimal('0.7E-18')
  1267. BigDecimal.save_limit do
  1268. BigDecimal.limit(0)
  1269. assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(0) #{bug7458}")
  1270. 1.upto(18) do |lim|
  1271. BigDecimal.limit(lim)
  1272. assert_equal(BigDecimal("1.0"), one + epsilon, "limit(#{lim}) #{bug7458}")
  1273. end
  1274. BigDecimal.limit(19)
  1275. assert_equal(BigDecimal("1.000000000000000001"), one + epsilon, "limit(19) #{bug7458}")
  1276. BigDecimal.limit(20)
  1277. assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(20) #{bug7458}")
  1278. end
  1279. end
  1280. def test_sign
  1281. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1282. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1283. BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
  1284. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal("0").sign)
  1285. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal("-0").sign)
  1286. assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal("1").sign)
  1287. assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal("-1").sign)
  1288. assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal("1") / 0).sign)
  1289. assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal("-1") / 0).sign)
  1290. assert_equal(BigDecimal::SIGN_NaN, (BigDecimal("0") / 0).sign)
  1291. end
  1292. def test_inf
  1293. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1294. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1295. inf = BigDecimal("Infinity")
  1296. assert_equal(inf, inf + inf)
  1297. assert_nan((inf + (-inf)))
  1298. assert_nan((inf - inf))
  1299. assert_equal(inf, inf - (-inf))
  1300. assert_equal(inf, inf * inf)
  1301. assert_nan((inf / inf))
  1302. assert_equal(inf, inf + 1)
  1303. assert_equal(inf, inf - 1)
  1304. assert_equal(inf, inf * 1)
  1305. assert_nan((inf * 0))
  1306. assert_equal(inf, inf / 1)
  1307. assert_equal(inf, 1 + inf)
  1308. assert_equal(-inf, 1 - inf)
  1309. assert_equal(inf, 1 * inf)
  1310. assert_equal(-inf, -1 * inf)
  1311. assert_nan((0 * inf))
  1312. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
  1313. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
  1314. end
  1315. def test_to_special_string
  1316. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1317. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1318. nan = BigDecimal("NaN")
  1319. assert_equal("NaN", nan.to_s)
  1320. inf = BigDecimal("Infinity")
  1321. assert_equal("Infinity", inf.to_s)
  1322. assert_equal(" Infinity", inf.to_s(" "))
  1323. assert_equal("+Infinity", inf.to_s("+"))
  1324. assert_equal("-Infinity", (-inf).to_s)
  1325. pzero = BigDecimal("0")
  1326. assert_equal("0.0", pzero.to_s)
  1327. assert_equal(" 0.0", pzero.to_s(" "))
  1328. assert_equal("+0.0", pzero.to_s("+"))
  1329. assert_equal("-0.0", (-pzero).to_s)
  1330. end
  1331. def test_to_string
  1332. assert_equal("0.01", BigDecimal("0.01").to_s("F"))
  1333. s = "0." + "0" * 100 + "1"
  1334. assert_equal(s, BigDecimal(s).to_s("F"))
  1335. s = "1" + "0" * 100 + ".0"
  1336. assert_equal(s, BigDecimal(s).to_s("F"))
  1337. end
  1338. def test_ctov
  1339. assert_equal(0.1, BigDecimal("1E-1"))
  1340. assert_equal(10, BigDecimal("1E+1"))
  1341. assert_equal(1, BigDecimal("+1"))
  1342. BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
  1343. assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal("1E1" + "0" * 10000).sign)
  1344. assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal("-1E1" + "0" * 10000).sign)
  1345. assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal("1E-1" + "0" * 10000).sign)
  1346. assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal("-1E-1" + "0" * 10000).sign)
  1347. end
  1348. def test_split_under_gc_stress
  1349. bug3258 = '[ruby-dev:41213]'
  1350. expect = 10.upto(20).map{|i|[1, "1", 10, i+1].inspect}
  1351. assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, expect, [], bug3258)
  1352. GC.stress = true
  1353. 10.upto(20) do |i|
  1354. p BigDecimal("1"+"0"*i).split
  1355. end
  1356. EOS
  1357. end
  1358. def test_coerce_under_gc_stress
  1359. assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
  1360. expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
  1361. b = BigDecimal("1")
  1362. GC.stress = true
  1363. 10.times do
  1364. begin
  1365. b.coerce(:too_long_to_embed_as_string)
  1366. rescue => e
  1367. raise unless e.is_a?(TypeError)
  1368. raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
  1369. end
  1370. end
  1371. EOS
  1372. end
  1373. def test_INFINITY
  1374. assert_positive_infinite(BigDecimal::INFINITY)
  1375. end
  1376. def test_NAN
  1377. assert_nan(BigDecimal::NAN)
  1378. end
  1379. def test_exp_with_zero_precision
  1380. assert_raise(ArgumentError) do
  1381. BigMath.exp(1, 0)
  1382. end
  1383. end
  1384. def test_exp_with_negative_precision
  1385. assert_raise(ArgumentError) do
  1386. BigMath.exp(1, -42)
  1387. end
  1388. end
  1389. def test_exp_with_complex
  1390. assert_raise(ArgumentError) do
  1391. BigMath.exp(Complex(1, 2), 20)
  1392. end
  1393. end
  1394. def test_exp_with_negative
  1395. x = BigDecimal(-1)
  1396. y = BigMath.exp(x, 20)
  1397. assert_equal(y, BigMath.exp(-1, 20))
  1398. assert_equal(BigDecimal(-1), x)
  1399. end
  1400. def test_exp_with_negative_infinite
  1401. BigDecimal.save_exception_mode do
  1402. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1403. assert_equal(0, BigMath.exp(-BigDecimal::INFINITY, 20))
  1404. end
  1405. end
  1406. def test_exp_with_positive_infinite
  1407. BigDecimal.save_exception_mode do
  1408. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1409. assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0)
  1410. assert_positive_infinite(BigMath.exp(BigDecimal::INFINITY, 20))
  1411. end
  1412. end
  1413. def test_exp_with_nan
  1414. BigDecimal.save_exception_mode do
  1415. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1416. assert_nan(BigMath.exp(BigDecimal::NAN, 20))
  1417. end
  1418. end
  1419. def test_exp_with_1
  1420. assert_in_epsilon(Math::E, BigMath.exp(1, 20))
  1421. end
  1422. def test_BigMath_exp
  1423. prec = 20
  1424. assert_in_epsilon(Math.exp(20), BigMath.exp(BigDecimal("20"), prec))
  1425. assert_in_epsilon(Math.exp(40), BigMath.exp(BigDecimal("40"), prec))
  1426. assert_in_epsilon(Math.exp(-20), BigMath.exp(BigDecimal("-20"), prec))
  1427. assert_in_epsilon(Math.exp(-40), BigMath.exp(BigDecimal("-40"), prec))
  1428. end
  1429. def test_BigMath_exp_with_float
  1430. prec = 20
  1431. assert_in_epsilon(Math.exp(20), BigMath.exp(20.0, prec))
  1432. assert_in_epsilon(Math.exp(40), BigMath.exp(40.0, prec))
  1433. assert_in_epsilon(Math.exp(-20), BigMath.exp(-20.0, prec))
  1434. assert_in_epsilon(Math.exp(-40), BigMath.exp(-40.0, prec))
  1435. end
  1436. def test_BigMath_exp_with_fixnum
  1437. prec = 20
  1438. assert_in_epsilon(Math.exp(20), BigMath.exp(20, prec))
  1439. assert_in_epsilon(Math.exp(40), BigMath.exp(40, prec))
  1440. assert_in_epsilon(Math.exp(-20), BigMath.exp(-20, prec))
  1441. assert_in_epsilon(Math.exp(-40), BigMath.exp(-40, prec))
  1442. end
  1443. def test_BigMath_exp_with_rational
  1444. prec = 20
  1445. assert_in_epsilon(Math.exp(20), BigMath.exp(Rational(40,2), prec))
  1446. assert_in_epsilon(Math.exp(40), BigMath.exp(Rational(80,2), prec))
  1447. assert_in_epsilon(Math.exp(-20), BigMath.exp(Rational(-40,2), prec))
  1448. assert_in_epsilon(Math.exp(-40), BigMath.exp(Rational(-80,2), prec))
  1449. end
  1450. def test_BigMath_exp_under_gc_stress
  1451. assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
  1452. expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
  1453. 10.times do
  1454. begin
  1455. BigMath.exp(:too_long_to_embed_as_string, 6)
  1456. rescue => e
  1457. raise unless e.is_a?(ArgumentError)
  1458. raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
  1459. end
  1460. end
  1461. EOS
  1462. end
  1463. def test_BigMath_log_with_string
  1464. assert_raise(ArgumentError) do
  1465. BigMath.log("foo", 20)
  1466. end
  1467. end
  1468. def test_BigMath_log_with_nil
  1469. assert_raise(ArgumentError) do
  1470. BigMath.log(nil, 20)
  1471. end
  1472. end
  1473. def test_BigMath_log_with_non_integer_precision
  1474. assert_raise(ArgumentError) do
  1475. BigMath.log(1, 0.5)
  1476. end
  1477. end
  1478. def test_BigMath_log_with_nil_precision
  1479. assert_raise(ArgumentError) do
  1480. BigMath.log(1, nil)
  1481. end
  1482. end
  1483. def test_BigMath_log_with_complex
  1484. assert_raise(Math::DomainError) do
  1485. BigMath.log(Complex(1, 2), 20)
  1486. end
  1487. end
  1488. def test_BigMath_log_with_zero_arg
  1489. assert_raise(Math::DomainError) do
  1490. BigMath.log(0, 20)
  1491. end
  1492. end
  1493. def test_BigMath_log_with_negative_arg
  1494. assert_raise(Math::DomainError) do
  1495. BigMath.log(-1, 20)
  1496. end
  1497. end
  1498. def test_BigMath_log_with_zero_precision
  1499. assert_raise(ArgumentError) do
  1500. BigMath.log(1, 0)
  1501. end
  1502. end
  1503. def test_BigMath_log_with_negative_precision
  1504. assert_raise(ArgumentError) do
  1505. BigMath.log(1, -42)
  1506. end
  1507. end
  1508. def test_BigMath_log_with_negative_infinite
  1509. BigDecimal.save_exception_mode do
  1510. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1511. assert_raise(Math::DomainError) do
  1512. BigMath.log(-BigDecimal::INFINITY, 20)
  1513. end
  1514. end
  1515. end
  1516. def test_BigMath_log_with_positive_infinite
  1517. BigDecimal.save_exception_mode do
  1518. BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
  1519. assert(BigMath.log(BigDecimal::INFINITY, 20) > 0)
  1520. assert_positive_infinite(BigMath.log(BigDecimal::INFINITY, 20))
  1521. end
  1522. end
  1523. def test_BigMath_log_with_nan
  1524. BigDecimal.save_exception_mode do
  1525. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1526. assert_nan(BigMath.log(BigDecimal::NAN, 20))
  1527. end
  1528. end
  1529. def test_BigMath_log_with_float_nan
  1530. BigDecimal.save_exception_mode do
  1531. BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
  1532. assert_nan(BigMath.log(Float::NAN, 20))
  1533. end
  1534. end
  1535. def test_BigMath_log_with_1
  1536. assert_in_delta(0.0, BigMath.log(1, 20))
  1537. assert_in_delta(0.0, BigMath.log(1.0, 20))
  1538. assert_in_delta(0.0, BigMath.log(BigDecimal(1), 20))
  1539. end
  1540. def test_BigMath_log_with_exp_1
  1541. assert_in_delta(1.0, BigMath.log(BigMath.E(10), 10))
  1542. end
  1543. def test_BigMath_log_with_2
  1544. assert_in_delta(Math.log(2), BigMath.log(2, 20))
  1545. assert_in_delta(Math.log(2), BigMath.log(2.0, 20))
  1546. assert_in_delta(Math.log(2), BigMath.log(BigDecimal(2), 20))
  1547. end
  1548. def test_BigMath_log_with_square_of_E
  1549. assert_in_delta(2, BigMath.log(BigMath.E(20)**2, 20))
  1550. end
  1551. def test_BigMath_log_with_high_precision_case
  1552. e = BigDecimal('2.71828182845904523536028747135266249775724709369996')
  1553. e_3 = e.mult(e, 50).mult(e, 50)
  1554. log_3 = BigMath.log(e_3, 50)
  1555. assert_in_delta(3, log_3, 0.0000000000_0000000000_0000000000_0000000000_0000000001)
  1556. end
  1557. def test_BigMath_log_with_42
  1558. assert_in_delta(Math.log(42), BigMath.log(42, 20))
  1559. assert_in_delta(Math.log(42), BigMath.log(42.0, 20))
  1560. assert_in_delta(Math.log(42), BigMath.log(BigDecimal(42), 20))
  1561. end
  1562. def test_BigMath_log_with_101
  1563. # this is mainly a performance test (should be very fast, not the 0.3 s)
  1564. assert_in_delta(Math.log(101), BigMath.log(101, 20), 1E-15)
  1565. end
  1566. def test_BigMath_log_with_reciprocal_of_42
  1567. assert_in_delta(Math.log(1e-42), BigMath.log(1e-42, 20))
  1568. assert_in_delta(Math.log(1e-42), BigMath.log(BigDecimal("1e-42"), 20))
  1569. end
  1570. def test_BigMath_log_under_gc_stress
  1571. assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
  1572. expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
  1573. 10.times do
  1574. begin
  1575. BigMath.log(:too_long_to_embed_as_string, 6)
  1576. rescue => e
  1577. raise unless e.is_a?(ArgumentError)
  1578. raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
  1579. end
  1580. end
  1581. EOS
  1582. end
  1583. def test_frozen_p
  1584. x = BigDecimal(1)
  1585. assert(x.frozen?)
  1586. assert((x + x).frozen?)
  1587. end
  1588. def test_clone
  1589. assert_warning(/^$/) do
  1590. x = BigDecimal(0)
  1591. assert_same(x, x.clone)
  1592. end
  1593. end
  1594. def test_dup
  1595. assert_warning(/^$/) do
  1596. [1, -1, 2**100, -2**100].each do |i|
  1597. x = BigDecimal(i)
  1598. assert_same(x, x.dup)
  1599. end
  1600. end
  1601. end
  1602. def test_new_subclass
  1603. c = Class.new(BigDecimal)
  1604. assert_raise_with_message(NoMethodError, /undefined method `new'/) { c.new(1) }
  1605. end
  1606. def test_to_d
  1607. bug6093 = '[ruby-core:42969]'
  1608. code = "exit(BigDecimal('10.0') == 10.0.to_d)"
  1609. assert_ruby_status(%w[-rbigdecimal -rbigdecimal/util -rmathn -], code, bug6093)
  1610. end if RUBY_VERSION < '2.5' # mathn was removed from Ruby 2.5
  1611. def test_bug6406
  1612. assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
  1613. Thread.current.keys.to_s
  1614. EOS
  1615. end
  1616. def assert_no_memory_leak(code, *rest, **opt)
  1617. code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}"
  1618. super(["-rbigdecimal"],
  1619. "b = BigDecimal('10'); b.nil?; " \
  1620. "GC.add_stress_to_class(BigDecimal); "\
  1621. "#{code}", code, *rest, rss: true, limit: 1.1, **opt)
  1622. end
  1623. if EnvUtil.gc_stress_to_class?
  1624. def test_no_memory_leak_allocate
  1625. assert_no_memory_leak("BigDecimal.allocate")
  1626. end
  1627. def test_no_memory_leak_initialize
  1628. assert_no_memory_leak("BigDecimal()")
  1629. end
  1630. def test_no_memory_leak_BigDecimal
  1631. assert_no_memory_leak("BigDecimal('10')")
  1632. assert_no_memory_leak("BigDecimal(b)")
  1633. end
  1634. def test_no_memory_leak_create
  1635. assert_no_memory_leak("b + 10")
  1636. end
  1637. end
  1638. end