123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 | test "basic float arithmetic"
>> n := Float64(1.5)
>> n + n
>> n * 2
>> n - n
assert n == 1.5
assert n + n == 3.
assert n * 2 == 3.
assert n - n == 0.
test "float literals are inexact"
>> Float64(0.1) + Float64(0.2)
assert Float64(0.1) + Float64(0.2) != Float64(0.3)
assert (Float64(0.1) + Float64(0.2)).near(0.3)
test "float literals in arithmetic take the float's type"
# A bare literal is untyped: in arithmetic with a float it becomes that
# float type rather than pulling the operation into the exact-real `Num`
# (a `Num` value can't be assigned to a `Float64`, so these declarations
# only typecheck if the arithmetic really is Float64/Float32 arithmetic).
x := Float64(1.5)
>> half : Float64 = 0.5 * x
scaled : Float64 = x * 0.5
shifted : Float64 = x + 1.0
dropped : Float64 = x - 0.5
quotient : Float64 = x / 2.0
powered : Float64 = 2.0 ^ x
assert half == 0.75
assert scaled == 0.75
assert shifted == 2.5
assert dropped == 1.
assert quotient == 0.75
assert powered == Float64(2) ^ Float64(1.5)
f32 := Float32(1.5)
small : Float32 = 0.5 * f32
assert small == Float32(0.75)
# Literal-only subexpressions push down the same way, however deep:
nested : Float64 = (1.0/2.0) * x
deeper : Float64 = x * (1.0 + 1.0/2.0)
assert nested == 0.75
assert deeper == 2.25
# ...but only literals do: an actual `Num` value stays exact and does not
# silently become a float.
n := 1./3.
assert n * 3 == 1
assert Int64(3) * (1./3.) == 1
test "floored division"
# `/` is ordinary float division; `//` is floor(x/y), plain floor and not
# the Euclidean quotient the integer types and Num use, so for a negative
# divisor it rounds down rather than keeping the remainder non-negative.
assert Float64(7.5) / Float64(2) == 3.75
assert Float64(7.5) // Float64(2) == 3.
assert Float64(-7.5) // Float64(2) == -4.
assert Float64(7.5) // Float64(-2) == -4.
assert Float32(7.5) // Float32(2) == Float32(3)
test "constants"
>> Float64.PI
>> Float64.PI.with_precision(0.01)
>> Float64.INF
>> Float64.INF.isinf()
assert Float64.PI == 3.141592653589793
assert Float64.PI.with_precision(0.01) == 3.14
assert Float64.INF == Float64.INF
assert Float64.INF.isinf()
test "optional none floats"
>> none_num : Float64? = none
>> none_num
assert none_num == none
assert none_num == none_num
assert not (none_num < none_num)
assert not (none_num > none_num)
assert not (none_num != none_num)
assert (none_num <> none_num) == Int32(0)
assert not (none_num == 0.0)
assert none_num < 0.0
assert not (none_num > 0.0)
assert none_num != 0.0
assert (none_num <> 0.0) == Int32(-1)
test "math functions"
>> Float64.PI.cos()!
>> Float64.PI.sin()!
>> Float32.sqrt(16)
>> Float32.sqrt(-1)
>> Float64(0.25).mix(10, 20)
>> Float64(2.0).mix(10, 20)
>> Float64(5)
>> Float64(0.5).percent()
assert Float64.PI.cos()!.near(-1)
assert Float64.PI.sin()!.near(0)
assert not Float64.INF.near(-Float64.INF)
assert Float32.sqrt(16) == Float32(4)
assert Float32.sqrt(-1) == none
assert Float64(0.25).mix(10, 20) == 12.5
assert Float64(2.0).mix(10, 20) == 30.
assert Float64(5) == 5.
assert Float64(0.5).percent() == "50%"
test "force-unwrapping the square root of a negative panics"
_ := Float64.sqrt(-1.0)!
fails "This was expected to be a value, but it's `none`"
|