// Number retains integer or floating values; primitive types remain available.
fn increment(value: Number, step: Number = 1) -> Number {
    return value + step
}

fn sample(use_integer: Bool) {
    if use_integer { return 7 }
    return 7.5
}

class Cell<T> {
    public var value: T
    fn get() { return value }
}

var value: Number = 42
print(type(value)) // Int64
value = 2.5
print(type(value)) // Float64
print(dtype(value)) // Float64
print(increment(2)) // 3
print(increment(2.5)) // 3.5
print(type(sample(true))) // Int64
print(type(sample(false))) // Float64

let cell = Cell<Number>(value: 3)
cell.value = 3.5
print(cell.get()) // 3.5
let present: Optional<Number> = Optional.some(4)
print(present.unwrap() + 0.5) // 4.5

print(2 + 0.5) // 2.5
print(5 / 2) // 2.5
print(integer_div(-7, 3)) // -2
print(-7 % 3) // -1
print(9007199254740993 > 9007199254740992.0) // true

let exact: Float64 = 42
print(exact) // 42.0
let rounded = Float64(9007199254740993)
print(rounded == 9007199254740992.0) // true
print(Int64(3.9)) // 3
let dynamic: Any = 42
print(cast<Number>(dynamic) + 0.5) // 42.5

// These require explicit rounding rather than implicit promotion:
// let inexact: Float64 = 9007199254740993
// print(9007199254740993 + 0.5)
