#!/usr/bin/ruby

# Various other tests for the Number methods.
# Some tests are translated from the SymPy library.

define oo = Inf
define E = Num.e
define pi = Num.pi
define nan = NaN
define I = 1i

## FLOOR ##

assert(floor(nan).is_nan)

assert(floor(oo).is_inf)
assert(floor(-oo).is_ninf)

assert(floor(0) == 0)
assert(floor(1) == 1)
assert(floor(-1) == -1)

assert(floor(float(0)).is_zero)
assert(ceil(float(0)).is_zero)

assert(floor(E) == 2)
assert(floor(-E) == -3)

assert(floor(2*E) == 5)
assert(floor(-2*E) == -6)

assert(floor(pi) == 3)
assert(floor(-pi) == -4)

assert(floor(Fraction(-1, 2)) == -1)
assert(floor(Fraction(7, 3)) == 2)
assert(floor(Fraction(-7, 3)) == -3)
assert(floor(-Fraction(7, 3)) == -3)

assert(floor(float(17.0)) == 17)
assert(floor(-float(17.0)) == -17)

assert(floor(float(7.69)) == 7)
assert(floor(-float(7.69)) == -8)

assert(floor(I) == I)
assert(floor(-I) == -I)

#assert(floor(oo*I) == oo*I)
#assert(floor(-oo*I) == -oo*I)
assert(floor(exp(I*pi/4)*oo) == exp(I*pi/4)*oo)

assert(floor(2*I) == 2*I)
assert(floor(-2*I) == -2*I)

assert(floor(I/2) == 0)
assert(floor(-I/2) == -I)

assert(floor(E + 17) == 19)
assert(floor(pi + 2) == 5)

assert(floor(E + pi) == 5)
assert(floor(I + pi) == 3+I)

assert(floor(floor(pi)) == 3)

assert(floor(Fraction(23, 10) - E*I) == 2-3*I)

assert(floor(sin(1)) == 0)
assert(floor(sin(-1)) == -1)

assert(floor(exp(2)) == 7)

do {
    local Num!PREC = 1024.numify
    assert(floor(log(8)/log(2)) != 2)
    assert(int(floor(log(8)/log(2))) == 3)
    assert(floor(factorial(50)/exp(1)) == 11188719610782480504630258070757734324011354208865721592720336800)
}


## CEIL ##

assert(ceiling(nan).is_nan)

assert(ceiling(oo) == oo)
assert(ceiling(-oo) == -oo)

assert(ceiling(0) == 0)

assert(ceiling(1) == 1)
assert(ceiling(-1) == -1)

assert(ceiling(E) == 3)
assert(ceiling(-E) == -2)

assert(ceiling(2*E) == 6)
assert(ceiling(-2*E) == -5)

assert(ceiling(pi) == 4)
assert(ceiling(-pi) == -3)

assert(ceiling(Fraction(-1, 2)) == 0)
assert(ceiling(Fraction(7, 3)) == 3)
assert(ceiling(-Fraction(7, 3)) == -2)

assert(ceiling(float(17.0)) == 17)
assert(ceiling(-float(17.0)) == -17)

assert(ceiling(float(7.69)) == 8)
assert(ceiling(-float(7.69)) == -7)

assert(ceiling(I) == I)
assert(ceiling(-I) == -I)

#assert(ceiling(oo*I) == oo*I)
#assert(ceiling(-oo*I) == -oo*I)
assert(ceiling(exp(I*pi/4)*oo) == exp(I*pi/4)*oo)

assert(ceiling(2*I) == 2*I)
assert(ceiling(-2*I) == -2*I)

assert(ceiling(I/2) == I)
assert(ceiling(-I/2) == 0)

assert(ceiling(E + 17) == 20)
assert(ceiling(pi + 2) == 6)

assert(ceiling(E + pi) == 6)
assert(ceiling(I + pi) == I+4)

assert(ceiling(ceiling(pi)) == 4)
assert(ceiling(Fraction(23, 10) - E*I) == 3-2*I)

assert(ceiling(sin(1)) == 1)
assert(ceiling(sin(-1)) == 0)

assert(ceiling(exp(2)) == 8)

do {
    local Num!PREC = 1024.numify
    assert(ceiling(-log(8)/log(2)) != -2)
    assert(int(ceiling(-log(8)/log(2))) == -3)
    assert(ceiling(factorial(50)/exp(1)) == 11188719610782480504630258070757734324011354208865721592720336801)
}

## OTHER TESTS ##

with (irand(-1e6, 1e6)) {|y|

    assert(floor(3 + pi*I + y*I) == (3 + floor(pi + y)*I))
    assert(floor(3*I + pi*I + y*I) == (floor(3 + pi + y)*I))
    assert(floor(3 + E + pi*I + y*I) == (5 + floor(pi + y)*I))

    for x in ([y+1, y-1, -y, y.rat, y.float, y.complex]) {
        assert(floor(floor(x)) == floor(x))
        assert(floor(ceiling(x)) == ceiling(x))
        assert(ceiling(floor(x)) == floor(x))
        assert(ceiling(ceiling(x)) == ceiling(x))

        assert(floor(-floor(ceiling(x**3)/y)) == -floor(ceiling(x**3)/y))
        assert(ceiling(-floor(ceiling(x**3)/y)) == -floor(ceiling(x**3)/y))
        assert(floor(ceiling(-floor(x**Fraction(7, 2)/y))) == -floor(x**Fraction(7, 2)/y))
        assert(-ceiling(-ceiling(floor(x)/y)) == ceiling(floor(x)/y))

        assert(floor(floor(floor(x)) + 3) == (floor(x) + 3))
        assert(ceiling(ceiling(ceiling(x)) + 1) == (ceiling(x) + 1))
        assert(ceiling(ceiling(floor(x)) + 3) == (floor(x) + 3))
    }
}

say "** Test passed!"
