1require 'test/unit'
2require_relative 'envutil'
3
4class TestFloat < Test::Unit::TestCase
5  include EnvUtil
6
7  def test_float
8    assert_equal(2, 2.6.floor)
9    assert_equal(-3, (-2.6).floor)
10    assert_equal(3, 2.6.ceil)
11    assert_equal(-2, (-2.6).ceil)
12    assert_equal(2, 2.6.truncate)
13    assert_equal(-2, (-2.6).truncate)
14    assert_equal(3, 2.6.round)
15    assert_equal(-2, (-2.4).truncate)
16    assert((13.4 % 1 - 0.4).abs < 0.0001)
17    assert_equal(36893488147419111424,
18                 36893488147419107329.0.to_i)
19  end
20
21  def nan_test(x,y)
22    extend Test::Unit::Assertions
23    assert(x != y)
24    assert_equal(false, (x < y))
25    assert_equal(false, (x > y))
26    assert_equal(false, (x <= y))
27    assert_equal(false, (x >= y))
28  end
29  def test_nan
30    nan = Float::NAN
31    nan_test(nan, nan)
32    nan_test(nan, 0)
33    nan_test(nan, 1)
34    nan_test(nan, -1)
35    nan_test(nan, 1000)
36    nan_test(nan, -1000)
37    nan_test(nan, 1_000_000_000_000)
38    nan_test(nan, -1_000_000_000_000)
39    nan_test(nan, 100.0);
40    nan_test(nan, -100.0);
41    nan_test(nan, 0.001);
42    nan_test(nan, -0.001);
43    nan_test(nan, 1.0/0);
44    nan_test(nan, -1.0/0);
45  end
46
47  def test_precision
48    u = 3.7517675036461267e+17
49    v = sprintf("%.16e", u).to_f
50    assert_in_delta(u, v, u.abs * Float::EPSILON)
51    assert_in_delta(u, v, v.abs * Float::EPSILON)
52  end
53
54  def test_symmetry_bignum # [ruby-bugs-ja:118]
55    a = 100000000000000000000000
56    b = 100000000000000000000000.0
57    assert_equal(a == b, b == a)
58  end
59
60  def test_cmp_int
61    100.times {|i|
62      int0 = 1 << i
63      [int0, -int0].each {|int|
64        flt = int.to_f
65        bigger = int + 1
66        smaller = int - 1
67        assert_operator(flt, :==, int)
68        assert_operator(flt, :>, smaller)
69        assert_operator(flt, :>=, smaller)
70        assert_operator(flt, :<, bigger)
71        assert_operator(flt, :<=, bigger)
72        assert_equal(0, flt <=> int)
73        assert_equal(-1, flt <=> bigger)
74        assert_equal(1, flt <=> smaller)
75        assert_operator(int, :==, flt)
76        assert_operator(bigger, :>, flt)
77        assert_operator(bigger, :>=, flt)
78        assert_operator(smaller, :<, flt)
79        assert_operator(smaller, :<=, flt)
80        assert_equal(0, int <=> flt)
81        assert_equal(-1, smaller <=> flt)
82        assert_equal(1, bigger <=> flt)
83        [
84          [int, flt + 0.5, bigger],
85          [smaller, flt - 0.5, int]
86        ].each {|smaller2, flt2, bigger2|
87          next if flt2 == flt2.round
88          assert_operator(flt2, :!=, smaller2)
89          assert_operator(flt2, :!=, bigger2)
90          assert_operator(flt2, :>, smaller2)
91          assert_operator(flt2, :>=, smaller2)
92          assert_operator(flt2, :<, bigger2)
93          assert_operator(flt2, :<=, bigger2)
94          assert_equal(-1, flt2 <=> bigger2)
95          assert_equal(1, flt2 <=> smaller2)
96          assert_operator(smaller2, :!=, flt2)
97          assert_operator(bigger2, :!=, flt2)
98          assert_operator(bigger2, :>, flt2)
99          assert_operator(bigger2, :>=, flt2)
100          assert_operator(smaller2, :<, flt2)
101          assert_operator(smaller2, :<=, flt2)
102          assert_equal(-1, smaller2 <=> flt2)
103          assert_equal(1, bigger2 <=> flt2)
104        }
105      }
106    }
107  end
108
109  def test_strtod
110    a = Float("0")
111    assert(a.abs < Float::EPSILON)
112    a = Float("0.0")
113    assert(a.abs < Float::EPSILON)
114    a = Float("+0.0")
115    assert(a.abs < Float::EPSILON)
116    a = Float("-0.0")
117    assert(a.abs < Float::EPSILON)
118    a = Float("0.0000000000000000001")
119    assert(a != 0.0)
120    a = Float("+0.0000000000000000001")
121    assert(a != 0.0)
122    a = Float("-0.0000000000000000001")
123    assert(a != 0.0)
124    a = Float(".0")
125    assert(a.abs < Float::EPSILON)
126    a = Float("+.0")
127    assert(a.abs < Float::EPSILON)
128    a = Float("-.0")
129    assert(a.abs < Float::EPSILON)
130    assert_raise(ArgumentError){Float("0.")}
131    assert_raise(ArgumentError){Float("+0.")}
132    assert_raise(ArgumentError){Float("-0.")}
133    assert_raise(ArgumentError){Float(".")}
134    assert_raise(ArgumentError){Float("+")}
135    assert_raise(ArgumentError){Float("+.")}
136    assert_raise(ArgumentError){Float("-")}
137    assert_raise(ArgumentError){Float("-.")}
138    assert_raise(ArgumentError){Float("1e")}
139    assert_raise(ArgumentError){Float("1__1")}
140    assert_raise(ArgumentError){Float("1.")}
141    assert_raise(ArgumentError){Float("1.e+00")}
142    assert_raise(ArgumentError){Float("0x1.p+0")}
143    # add expected behaviour here.
144    assert_equal(10, Float("1_0"))
145
146    assert_equal([ 0.0].pack('G'), [Float(" 0x0p+0").to_f].pack('G'))
147    assert_equal([-0.0].pack('G'), [Float("-0x0p+0").to_f].pack('G'))
148    assert_equal(255.0,     Float("0Xff"))
149    assert_equal(1024.0,    Float("0x1p10"))
150    assert_equal(1024.0,    Float("0x1p+10"))
151    assert_equal(0.0009765625, Float("0x1p-10"))
152    assert_equal(2.6881171418161356e+43, Float("0x1.3494a9b171bf5p+144"))
153    assert_equal(-3.720075976020836e-44, Float("-0x1.a8c1f14e2af5dp-145"))
154    assert_equal(31.0*2**1019, Float("0x0."+("0"*268)+"1fp2099"))
155    assert_equal(31.0*2**1019, Float("0x0."+("0"*600)+"1fp3427"))
156    assert_equal(-31.0*2**1019, Float("-0x0."+("0"*268)+"1fp2099"))
157    assert_equal(-31.0*2**1019, Float("-0x0."+("0"*600)+"1fp3427"))
158    suppress_warning do
159      assert_equal(31.0*2**-1027, Float("0x1f"+("0"*268)+".0p-2099"))
160      assert_equal(31.0*2**-1027, Float("0x1f"+("0"*600)+".0p-3427"))
161      assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*268)+".0p-2099"))
162      assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*600)+".0p-3427"))
163    end
164  end
165
166  def test_divmod
167    assert_equal([2, 3.5], 11.5.divmod(4))
168    assert_equal([-3, -0.5], 11.5.divmod(-4))
169    assert_equal([-3, 0.5], (-11.5).divmod(4))
170    assert_equal([2, -3.5], (-11.5).divmod(-4))
171  end
172
173  def test_div
174    assert_equal(2, 11.5.div(4))
175    assert_equal(-3, 11.5.div(-4))
176    assert_equal(-3, (-11.5).div(4))
177    assert_equal(2, (-11.5).div(-4))
178  end
179
180  def test_modulo
181    assert_equal(3.5, 11.5.modulo(4))
182    assert_equal(-0.5, 11.5.modulo(-4))
183    assert_equal(0.5, (-11.5).modulo(4))
184    assert_equal(-3.5, (-11.5).modulo(-4))
185  end
186
187  def test_remainder
188    assert_equal(3.5, 11.5.remainder(4))
189    assert_equal(3.5, 11.5.remainder(-4))
190    assert_equal(-3.5, (-11.5).remainder(4))
191    assert_equal(-3.5, (-11.5).remainder(-4))
192  end
193
194  def test_to_s
195    inf = Float::INFINITY
196    assert_equal("Infinity", inf.to_s)
197    assert_equal("-Infinity", (-inf).to_s)
198    assert_equal("NaN", (inf / inf).to_s)
199
200    assert_equal("1.0e+18", 1000_00000_00000_00000.0.to_s)
201
202    bug3273 = '[ruby-core:30145]'
203    [0.21611564636388508, 0.56].each do |f|
204      s = f.to_s
205      assert_equal(f, s.to_f, bug3273)
206      assert_not_equal(f, s.chop.to_f, bug3273)
207    end
208  end
209
210  def test_coerce
211    assert_equal(Float, 1.0.coerce(1).first.class)
212  end
213
214  def test_plus
215    assert_equal(4.0, 2.0.send(:+, 2))
216    assert_equal(4.0, 2.0.send(:+, (2**32).coerce(2).first))
217    assert_equal(4.0, 2.0.send(:+, 2.0))
218    assert_raise(TypeError) { 2.0.send(:+, nil) }
219  end
220
221  def test_minus
222    assert_equal(0.0, 2.0.send(:-, 2))
223    assert_equal(0.0, 2.0.send(:-, (2**32).coerce(2).first))
224    assert_equal(0.0, 2.0.send(:-, 2.0))
225    assert_raise(TypeError) { 2.0.send(:-, nil) }
226  end
227
228  def test_mul
229    assert_equal(4.0, 2.0.send(:*, 2))
230    assert_equal(4.0, 2.0.send(:*, (2**32).coerce(2).first))
231    assert_equal(4.0, 2.0.send(:*, 2.0))
232    assert_raise(TypeError) { 2.0.send(:*, nil) }
233  end
234
235  def test_div2
236    assert_equal(1.0, 2.0.send(:/, 2))
237    assert_equal(1.0, 2.0.send(:/, (2**32).coerce(2).first))
238    assert_equal(1.0, 2.0.send(:/, 2.0))
239    assert_raise(TypeError) { 2.0.send(:/, nil) }
240  end
241
242  def test_modulo2
243    assert_equal(0.0, 2.0.send(:%, 2))
244    assert_equal(0.0, 2.0.send(:%, (2**32).coerce(2).first))
245    assert_equal(0.0, 2.0.send(:%, 2.0))
246    assert_raise(TypeError) { 2.0.send(:%, nil) }
247  end
248
249  def test_modulo3
250    bug6048 = '[ruby-core:42726]'
251    assert_equal(4.2, 4.2.send(:%, Float::INFINITY))
252    assert_equal(4.2, 4.2 % Float::INFINITY)
253    assert_is_minus_zero(-0.0 % 4.2)
254    assert_is_minus_zero(-0.0.send :%, 4.2)
255    assert_raise(ZeroDivisionError) { 4.2.send(:%, 0.0) }
256    assert_raise(ZeroDivisionError) { 4.2 % 0.0 }
257    assert_raise(ZeroDivisionError) { 42.send(:%, 0) }
258    assert_raise(ZeroDivisionError) { 42 % 0 }
259  end
260
261  def test_divmod2
262    assert_equal([1.0, 0.0], 2.0.divmod(2))
263    assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
264    assert_equal([1.0, 0.0], 2.0.divmod(2.0))
265    assert_raise(TypeError) { 2.0.divmod(nil) }
266
267    inf = Float::INFINITY
268    assert_raise(ZeroDivisionError) {inf.divmod(0)}
269
270    a, b = (2.0**32).divmod(1.0)
271    assert_equal(2**32, a)
272    assert_equal(0, b)
273  end
274
275  def test_pow
276    assert_equal(1.0, 1.0 ** (2**32))
277    assert_equal(1.0, 1.0 ** 1.0)
278    assert_raise(TypeError) { 1.0 ** nil }
279  end
280
281  def test_eql
282    inf = Float::INFINITY
283    nan = Float::NAN
284    assert(1.0.eql?(1.0))
285    assert(inf.eql?(inf))
286    assert(!(nan.eql?(nan)))
287    assert(!(1.0.eql?(nil)))
288
289    assert(1.0 == 1)
290    assert(1.0 != 2**32)
291    assert(1.0 != nan)
292    assert(1.0 != nil)
293  end
294
295  def test_cmp
296    inf = Float::INFINITY
297    nan = Float::NAN
298    assert_equal(0, 1.0 <=> 1.0)
299    assert_equal(1, 1.0 <=> 0.0)
300    assert_equal(-1, 1.0 <=> 2.0)
301    assert_nil(1.0 <=> nil)
302    assert_nil(1.0 <=> nan)
303    assert_nil(nan <=> 1.0)
304
305    assert_equal(0, 1.0 <=> 1)
306    assert_equal(1, 1.0 <=> 0)
307    assert_equal(-1, 1.0 <=> 2)
308
309    assert_equal(-1, 1.0 <=> 2**32)
310
311    assert_equal(1, inf <=> (Float::MAX.to_i*2))
312    assert_equal(-1, -inf <=> (-Float::MAX.to_i*2))
313    assert_equal(-1, (Float::MAX.to_i*2) <=> inf)
314    assert_equal(1, (-Float::MAX.to_i*2) <=> -inf)
315
316    bug3609 = '[ruby-core:31470]'
317    def (pinf = Object.new).infinite?; +1 end
318    def (ninf = Object.new).infinite?; -1 end
319    def (fin = Object.new).infinite?; nil end
320    nonum = Object.new
321    assert_equal(0, inf <=> pinf, bug3609)
322    assert_equal(1, inf <=> fin, bug3609)
323    assert_equal(1, inf <=> ninf, bug3609)
324    assert_nil(inf <=> nonum, bug3609)
325    assert_equal(-1, -inf <=> pinf, bug3609)
326    assert_equal(-1, -inf <=> fin, bug3609)
327    assert_equal(0, -inf <=> ninf, bug3609)
328    assert_nil(-inf <=> nonum, bug3609)
329
330    assert_raise(ArgumentError) { 1.0 > nil }
331    assert_raise(ArgumentError) { 1.0 >= nil }
332    assert_raise(ArgumentError) { 1.0 < nil }
333    assert_raise(ArgumentError) { 1.0 <= nil }
334  end
335
336  def test_zero_p
337    assert(0.0.zero?)
338    assert(!(1.0.zero?))
339  end
340
341  def test_infinite_p
342    inf = Float::INFINITY
343    assert_equal(1, inf.infinite?)
344    assert_equal(-1, (-inf).infinite?)
345    assert_nil(1.0.infinite?)
346  end
347
348  def test_finite_p
349    inf = Float::INFINITY
350    assert(!(inf.finite?))
351    assert(!((-inf).finite?))
352    assert(1.0.finite?)
353  end
354
355  def test_floor_ceil_round_truncate
356    assert_equal(1, 1.5.floor)
357    assert_equal(2, 1.5.ceil)
358    assert_equal(2, 1.5.round)
359    assert_equal(1, 1.5.truncate)
360
361    assert_equal(2, 2.0.floor)
362    assert_equal(2, 2.0.ceil)
363    assert_equal(2, 2.0.round)
364    assert_equal(2, 2.0.truncate)
365
366    assert_equal(-2, (-1.5).floor)
367    assert_equal(-1, (-1.5).ceil)
368    assert_equal(-2, (-1.5).round)
369    assert_equal(-1, (-1.5).truncate)
370
371    assert_equal(-2, (-2.0).floor)
372    assert_equal(-2, (-2.0).ceil)
373    assert_equal(-2, (-2.0).round)
374    assert_equal(-2, (-2.0).truncate)
375
376    inf = Float::INFINITY
377    assert_raise(FloatDomainError) { inf.floor }
378    assert_raise(FloatDomainError) { inf.ceil }
379    assert_raise(FloatDomainError) { inf.round }
380    assert_raise(FloatDomainError) { inf.truncate }
381  end
382
383  def test_round_with_precision
384    assert_equal(1.100, 1.111.round(1))
385    assert_equal(1.110, 1.111.round(2))
386    assert_equal(11110.0, 11111.1.round(-1))
387    assert_equal(11100.0, 11111.1.round(-2))
388
389    assert_equal(10**300, 1.1e300.round(-300))
390    assert_equal(-10**300, -1.1e300.round(-300))
391    assert_equal(1.0e-300, 1.1e-300.round(300))
392    assert_equal(-1.0e-300, -1.1e-300.round(300))
393
394    bug5227 = '[ruby-core:39093]'
395    assert_equal(42.0, 42.0.round(308), bug5227)
396    assert_equal(1.0e307, 1.0e307.round(2), bug5227)
397
398    assert_raise(TypeError) {1.0.round("4")}
399    assert_raise(TypeError) {1.0.round(nil)}
400    def (prec = Object.new).to_int; 2; end
401    assert_equal(1.0, 0.998.round(prec))
402  end
403
404  VS = [
405    18446744073709551617.0,
406    18446744073709551616.0,
407    18446744073709551615.8,
408    18446744073709551615.5,
409    18446744073709551615.2,
410    18446744073709551615.0,
411    18446744073709551614.0,
412
413    4611686018427387905.0,
414    4611686018427387904.0,
415    4611686018427387903.8,
416    4611686018427387903.5,
417    4611686018427387903.2,
418    4611686018427387903.0,
419    4611686018427387902.0,
420
421    4294967297.0,
422    4294967296.0,
423    4294967295.8,
424    4294967295.5,
425    4294967295.2,
426    4294967295.0,
427    4294967294.0,
428
429    1073741825.0,
430    1073741824.0,
431    1073741823.8,
432    1073741823.5,
433    1073741823.2,
434    1073741823.0,
435    1073741822.0,
436
437    -1073741823.0,
438    -1073741824.0,
439    -1073741824.2,
440    -1073741824.5,
441    -1073741824.8,
442    -1073741825.0,
443    -1073741826.0,
444
445    -4294967295.0,
446    -4294967296.0,
447    -4294967296.2,
448    -4294967296.5,
449    -4294967296.8,
450    -4294967297.0,
451    -4294967298.0,
452
453    -4611686018427387903.0,
454    -4611686018427387904.0,
455    -4611686018427387904.2,
456    -4611686018427387904.5,
457    -4611686018427387904.8,
458    -4611686018427387905.0,
459    -4611686018427387906.0,
460
461    -18446744073709551615.0,
462    -18446744073709551616.0,
463    -18446744073709551616.2,
464    -18446744073709551616.5,
465    -18446744073709551616.8,
466    -18446744073709551617.0,
467    -18446744073709551618.0,
468  ]
469
470  def test_truncate
471    VS.each {|f|
472      i = f.truncate
473      assert_equal(i, f.to_i)
474      if f < 0
475        assert_operator(i, :<, 0)
476      else
477        assert_operator(i, :>, 0)
478      end
479      assert_operator(i.abs, :<=, f.abs)
480      d = f.abs - i.abs
481      assert_operator(0, :<=, d)
482      assert_operator(d, :<, 1)
483    }
484  end
485
486  def test_ceil
487    VS.each {|f|
488      i = f.ceil
489      if f < 0
490        assert_operator(i, :<, 0)
491      else
492        assert_operator(i, :>, 0)
493      end
494      assert_operator(i, :>=, f)
495      d = f - i
496      assert_operator(-1, :<, d)
497      assert_operator(d, :<=, 0)
498    }
499  end
500
501  def test_floor
502    VS.each {|f|
503      i = f.floor
504      if f < 0
505        assert_operator(i, :<, 0)
506      else
507        assert_operator(i, :>, 0)
508      end
509      assert_operator(i, :<=, f)
510      d = f - i
511      assert_operator(0, :<=, d)
512      assert_operator(d, :<, 1)
513    }
514  end
515
516  def test_round
517    VS.each {|f|
518      msg = "round(#{f})"
519      i = f.round
520      if f < 0
521        assert_operator(i, :<, 0, msg)
522      else
523        assert_operator(i, :>, 0, msg)
524      end
525      d = f - i
526      assert_operator(-0.5, :<=, d, msg)
527      assert_operator(d, :<=, 0.5, msg)
528    }
529  end
530
531  def test_Float
532    assert_in_delta(0.125, Float("0.1_2_5"), 0.00001)
533    assert_in_delta(0.125, "0.1_2_5__".to_f, 0.00001)
534    assert_equal(1, suppress_warning {Float(([1] * 10000).join)}.infinite?)
535    assert(!Float(([1] * 10000).join("_")).infinite?) # is it really OK?
536    assert_raise(ArgumentError) { Float("1.0\x001") }
537    assert_equal(15.9375, Float('0xf.fp0'))
538    assert_raise(ArgumentError) { Float('0x') }
539    assert_equal(15, Float('0xf'))
540    assert_equal(15, Float('0xfp0'))
541    assert_raise(ArgumentError) { Float('0xfp') }
542    assert_raise(ArgumentError) { Float('0xf.') }
543    assert_raise(ArgumentError) { Float('0xf.p') }
544    assert_raise(ArgumentError) { Float('0xf.p0') }
545    assert_raise(ArgumentError) { Float('0xf.f') }
546    assert_raise(ArgumentError) { Float('0xf.fp') }
547    assert_equal(Float::INFINITY, Float('0xf.fp1000000000000000'))
548    assert_equal(1, suppress_warning {Float("1e10_00")}.infinite?)
549    assert_raise(TypeError) { Float(nil) }
550    o = Object.new
551    def o.to_f; inf = Float::INFINITY; inf/inf; end
552    assert(Float(o).nan?)
553  end
554
555  def test_invalid_str
556    bug4310 = '[ruby-core:34820]'
557    assert_raise(ArgumentError, bug4310) {under_gc_stress {Float('a'*10000)}}
558  end
559
560  def test_num2dbl
561    assert_raise(TypeError) do
562      1.0.step(2.0, "0.5") {}
563    end
564    assert_raise(TypeError) do
565      1.0.step(2.0, nil) {}
566    end
567  end
568
569  def test_sleep_with_Float
570    assert_nothing_raised("[ruby-core:23282]") do
571      sleep(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)
572    end
573  end
574
575  def test_step
576    1000.times do
577      a = rand
578      b = a+rand*1000
579      s = (b - a) / 10
580      assert_equal(11, (a..b).step(s).to_a.length)
581    end
582
583    (1.0..12.7).step(1.3).each do |n|
584      assert_operator(n, :<=, 12.7)
585    end
586
587    assert_equal([5.0, 4.0, 3.0, 2.0], 5.0.step(1.5, -1).to_a)
588  end
589
590  def test_step2
591    assert_equal([0.0], 0.0.step(1.0, Float::INFINITY).to_a)
592  end
593
594  def test_step_excl
595    1000.times do
596      a = rand
597      b = a+rand*1000
598      s = (b - a) / 10
599      assert_equal(10, (a...b).step(s).to_a.length)
600    end
601
602    assert_equal([1.0, 2.9, 4.8, 6.699999999999999], (1.0...6.8).step(1.9).to_a)
603
604    e = 1+1E-12
605    (1.0 ... e).step(1E-16) do |n|
606      assert_operator(n, :<=, e)
607    end
608  end
609
610  def test_singleton_method
611    # flonum on 64bit platform
612    assert_raise(TypeError) { a = 1.0; def a.foo; end }
613    # always not flonum
614    assert_raise(TypeError) { a = Float::INFINITY; def a.foo; end }
615  end
616
617  def test_long_string
618    assert_separately([], <<-'end;')
619    assert_in_epsilon(10.0, ("1."+"1"*300000).to_f*9)
620    end;
621  end
622end
623