///|
test "special float values" {
// Infinity values
inspect(@float.infinity, content="Infinity")
inspect(@float.neg_infinity, content="-Infinity")
// Not a Number
inspect(@float.not_a_number, content="NaN")
// Bounds
inspect(@float.max_value, content="3.4028234663852886e+38")
inspect(@float.min_value, content="-3.4028234663852886e+38")
inspect(@float.min_positive, content="1.1754943508222875e-38")
}
///|
test "checking special values" {
// Testing for special values
inspect(@float.infinity.is_inf(), content="true")
inspect(@float.neg_infinity.is_neg_inf(), content="true")
inspect(@float.infinity.is_pos_inf(), content="true")
inspect(@float.not_a_number.is_nan(), content="true")
}///|
test "rounding functions" {
// Ceiling - rounds up
inspect(@float.ceil(3.2), content="4")
inspect(@float.ceil(-3.2), content="-3")
// Floor - rounds down
inspect(@float.floor(3.2), content="3")
inspect(@float.floor(-3.2), content="-4")
// Round - rounds to nearest integer
inspect(@float.round(3.7), content="4")
inspect(@float.round(3.2), content="3")
// Truncate - removes decimal part
inspect(@float.trunc(3.7), content="3")
inspect(@float.trunc(-3.7), content="-3")
}///|
test "utility functions" {
// Absolute value
inspect(Float::abs(-3.14), content="3.140000104904175")
// Conversion to integer
inspect(3.14.to_int(), content="3")
// Default value
inspect((Default::default() : Float), content="0")
}///|
test "byte representation" {
let x : Float = 3.14
// Big-endian bytes
let be_bytes = x.to_be_bytes()
// Little-endian bytes
let le_bytes = x.to_le_bytes()
inspect(be_bytes.length(), content="4")
inspect(le_bytes.length(), content="4")
}///|
test "math functions" {
inspect(Float::sqrt(9.0), content="3")
inspect(Float::signum(-5.0), content="-1")
inspect(Float::min(1.0, 2.0), content="1")
inspect(Float::max(1.0, 2.0), content="2")
}///|
test "clamp and lerp" {
inspect(Float::clamp(5.0, min=0.0, max=3.0), content="3")
inspect(Float::clamp(-1.0, min=0.0, max=3.0), content="0")
inspect(Float::lerp(0.0, target=10.0, t=0.5), content="5")
}///|
test "is_close" {
let a : Float = 0.1 + 0.2
inspect(Float::is_close(a, 0.3, relative_tolerance=1.0e-6), content="true")
}///|
test "conversions" {
inspect(Float::from_int(42), content="42")
inspect(Float::from_double(3.14), content="3.140000104904175")
inspect(Float::from_int64(100L), content="100")
inspect(Float::from_uint(42U), content="42")
inspect(Float::from_byte(b'\x41'), content="65")
inspect((3.14 : Float).to_double(), content="3.140000104904175")
inspect((3.14 : Float).to_int(), content="3")
}///|
test "reinterpret" {
let f : Float = 1.0
let bits = f.reinterpret_as_int()
inspect(bits, content="1065353216") // IEEE 754: 0x3F800000
let roundtrip = Float::reinterpret_from_int(bits)
inspect(roundtrip, content="1")
// unsigned variant
let ubits = f.reinterpret_as_uint()
inspect(ubits, content="1065353216")
let roundtrip2 = Float::reinterpret_from_uint(ubits)
inspect(roundtrip2, content="1")
}///|
test "range" {
let values = Float::until(0.0, 1.0, step=0.5).to_array()
debug_inspect(values, content="[0, 0.5]")
let inclusive = Float::until(0.0, 1.0, step=0.5, inclusive=true).to_array()
debug_inspect(inclusive, content="[0, 0.5, 1]")
}Float is a built-in type. The documentation may not be complete here. You can find all methods and implementations in the core/builtin and core/float package.
#as_free_fn(deprecated="Use Float::abs instead.")
fn Float::abs(self : Float) -> Floattest {
inspect((1.5 : Float).abs(), content="1.5")
inspect((-1.5 : Float).abs(), content="1.5")
inspect((0.0 : Float).abs(), content="0")
inspect((-0.0 : Float).abs(), content="0")
inspect(@float.not_a_number.abs().is_nan(), content="true")
}#as_free_fn
fn Float::ceil(self : Float) -> Floattest {
inspect((1.5 : Float).ceil(), content="2")
inspect((1.0 : Float).ceil(), content="1")
inspect((-1.5 : Float).ceil(), content="-1")
}fn Float::clamp(self : Float, min~ : Float, max~ : Float) -> Floattest {
inspect((0.5 : Float).clamp(min=0.0, max=1.0), content="0.5")
inspect((-1.0 : Float).clamp(min=0.0, max=1.0), content="0")
inspect((2.0 : Float).clamp(min=0.0, max=1.0), content="1")
}#as_free_fn
fn Float::floor(self : Float) -> Floattest {
inspect((1.7 : Float).floor(), content="1")
inspect((-1.7 : Float).floor(), content="-2")
inspect((2.0 : Float).floor(), content="2")
}fn Float::from_byte(self : Byte) -> Floattest {
let b = b'\xFF' // 255 in decimal
let f = Float::from_byte(b)
// Convert to double for comparison since Float doesn't implement Show
inspect(f.to_double(), content="255")
}fn Float::from_double(self : Double) -> Floattest {
let d = 3.14159265359
inspect(Float::from_double(d).to_double(), content="3.1415927410125732") // Note the loss of precision
}fn Float::from_int(self : Int) -> Floattest {
let n = 42
let f = Float::from_int(n)
// Convert back to double for comparison since Float doesn't implement Show
inspect(f.to_double(), content="42")
}fn Float::from_int64(self : Int64) -> Floattest {
let n = 42L
let f = Float::from_int64(n)
// Convert to double for comparison since Float doesn't implement Show
inspect(f.to_double(), content="42")
}fn Float::from_uint(self : UInt) -> Floattest {
let n = 42U
inspect(Float::from_uint(n).to_double(), content="42")
let big = 16777216U // 2^24
inspect(Float::from_uint(big).to_double(), content="16777216") // Last precisely representable integer
}fn Float::from_uint64(self : UInt64) -> Floattest {
let n = 42UL
inspect(Float::from_uint64(n).to_double(), content="42")
let big = 18446744073709551615UL // UInt64::max_value
inspect(Float::from_uint64(big).to_double(), content="18446744073709552000")
}fn Float::is_close(self : Float, other : Float, relative_tolerance? : Float, absolute_tolerance? : Float) -> Booltest {
let x = 1.0
let y = 1.000000001
inspect(x.is_close(y), content="false")
inspect(x.is_close(y, relative_tolerance=1.0e-10), content="false")
inspect(@float.infinity.is_close(@float.infinity), content="true")
}fn Float::is_inf(self : Float) -> Booltest {
inspect(@float.infinity.is_inf(), content="true")
inspect(@float.neg_infinity.is_inf(), content="true")
inspect((1.0 : Float).is_inf(), content="false")
}fn Float::is_nan(self : Float) -> Booltest {
inspect(@float.not_a_number.is_nan(), content="true")
inspect((1.0 : Float).is_nan(), content="false")
inspect(@float.infinity.is_nan(), content="false")
}fn Float::is_neg_inf(self : Float) -> Booltest {
inspect(@float.neg_infinity.is_neg_inf(), content="true")
inspect((1.0 : Float).is_neg_inf(), content="false")
inspect(@float.infinity.is_neg_inf(), content="false")
}fn Float::is_pos_inf(self : Float) -> Booltest {
inspect(@float.infinity.is_pos_inf(), content="true")
inspect((1.0 : Float).is_pos_inf(), content="false")
inspect(@float.neg_infinity.is_pos_inf(), content="false")
}fn Float::lerp(self : Float, target~ : Float, t~ : Float) -> Floattest {
inspect((0.0 : Float).lerp(target=10.0, t=0.25), content="2.5")
inspect((5.0 : Float).lerp(target=15.0, t=0.0), content="5")
inspect((5.0 : Float).lerp(target=15.0, t=1.0), content="15")
}fn Float::max(self : Float, other : Float) -> Floatfn Float::min(self : Float, other : Float) -> Float#as_free_fn(deprecated="Use `@math.powf` instead")
#deprecated("Use `@math.powf` instead")
fn Float::pow(self : Float, other : Float) -> Floattest {
inspect(@math.powf(2.0, 3.0), content="8")
inspect(@math.powf(4.0, 0.5), content="2")
inspect(@math.powf(1.0, -1.0), content="1")
}fn Float::reinterpret_as_int(self : Float) -> Inttest {
let f = Float::from_double(1.0)
// IEEE 754 representation of 1.0 is 0x3F800000
inspect(f.reinterpret_as_int(), content="1065353216")
}fn Float::reinterpret_as_uint(self : Float) -> UInttest {
let x : Float = 1.0
inspect(x.reinterpret_as_uint(), content="1065353216") // Decimal representation of 0x3F800000
}fn Float::reinterpret_from_int(self : Int) -> Floattest {
// 0x3F800000 represents 1.0 in IEEE 754 single-precision format
let n = 1065353216 // 0x3F800000
inspect(Float::reinterpret_from_int(n), content="1")
}fn Float::reinterpret_from_uint(self : UInt) -> Floattest {
let n = 0x3F800000U // Bit pattern for 1.0f
inspect(Float::reinterpret_from_uint(n), content="1")
}#as_free_fn
fn Float::round(self : Float) -> Floattest {
inspect((2.3 : Float).round(), content="2")
inspect((2.5 : Float).round(), content="3")
inspect((-2.5 : Float).round(), content="-2")
}fn Float::signum(self : Float) -> Floatfn Float::sqrt(self : Float) -> Floattest {
let x = Float::from_double(16.0)
let root = x.sqrt()
inspect(root.to_double(), content="4")
let neg = Float::from_double(-4.0)
let neg_root = neg.sqrt()
inspect(neg_root.to_double(), content="NaN")
}fn Float::to_be_bytes(self : Float) -> Bytestest {
let x : Float = 1.0
inspect(
x.to_be_bytes(),
content=(
#|b"?\x80\x00\x00"
),
)
}fn Float::to_double(self : Float) -> Doubletest {
let f = Float::from_double(3.14)
inspect(f.to_double(), content="3.140000104904175")
}fn Float::to_int(self : Float) -> Inttest {
inspect((1.5 : Float).to_int(), content="1")
inspect((-1.5 : Float).to_int(), content="-1")
inspect(@float.not_a_number.to_int(), content="0")
inspect(@float.infinity.to_int(), content="2147483647")
inspect(@float.neg_infinity.to_int(), content="-2147483648")
}fn Float::to_le_bytes(self : Float) -> Bytestest {
let f : Float = 1.0
let bytes = f.to_le_bytes()
inspect(bytes.length(), content="4")
}#as_free_fn
fn Float::trunc(self : Float) -> Floattest {
inspect((3.7 : Float).trunc(), content="3")
inspect((-3.7 : Float).trunc(), content="-3")
inspect((0.2 : Float).trunc(), content="0")
}fn add(self : Float, other : Float) -> Floattest {
let a = Float::from_double(3.14)
let b = Float::from_double(2.86)
let sum = a + b
inspect(sum.to_double(), content="6")
}fn compare(self : Float, other : Float) -> Inttest {
let a = 3.14
let b = 2.718
inspect(a.compare(b), content="1") // 3.14 > 2.718
inspect(b.compare(a), content="-1") // 2.718 < 3.14
inspect(a.compare(a), content="0") // 3.14 = 3.14
}fn op_ge(x : Float, y : Float) -> Boolfn op_gt(x : Float, y : Float) -> Boolfn op_le(x : Float, y : Float) -> Boolfn op_lt(x : Float, y : Float) -> Boolfn default() -> Floattest {
inspect((Default::default() : Float), content="0")
}fn div(self : Float, other : Float) -> Floattest {
let a = Float::from_double(6.0)
let b = Float::from_double(2.0)
let result = (a / b).to_double()
inspect(result, content="3")
inspect(
(Float::from_double(0.0) / Float::from_double(0.0)).to_double(),
content="NaN",
)
}fn equal(self : Float, other : Float) -> Booltest {
let x = 3.14
let y = 3.14
let z = 0.0 / 0.0 // NaN
inspect(x == y, content="true")
inspect(z == z, content="false") // NaN is not equal to itself
}fn not_equal(self : Float, other : Float) -> Booltest {
let x = 3.14
let y = 3.14
let z = 0.0 / 0.0 // NaN
inspect(x != y, content="false")
inspect(z != z, content="true") // NaN is not equal to itself
}test {
let x : Float = 3.14
let y : Float = 3.14
// Same values should produce same hash combinations
inspect(Hash::hash(x) == Hash::hash(y), content="true")
}fn mod(self : Float, other : Float) -> Floattest {
inspect((5.7 : Float).mod(2.0), content="1.6999998092651367")
inspect((-5.7 : Float).mod(2.0), content="-1.6999998092651367")
}fn mul(self : Float, other : Float) -> Floattest {
let x = Float::from_int(2)
let y = Float::from_int(3)
let z = x * y
inspect(z.to_double(), content="6")
}fn neg(self : Float) -> Floattest {
let f = Float::from_double(3.14)
inspect((-f).to_double(), content="-3.140000104904175")
let zero = Float::from_double(0.0)
inspect((-zero).to_double(), content="0")
}fn sub(self : Float, other : Float) -> Floattest {
let x = Float::from_double(3.14)
let y = Float::from_double(1.0)
let result = x - y
inspect(result.to_double(), content="2.140000104904175")
}#deprecated("This function is deprecated.")
fn default() -> Floatlet infinity : Floattest {
inspect(@float.infinity.is_pos_inf(), content="true")
inspect(@float.infinity > 1.0, content="true")
}let max_value : Floattest {
inspect(@float.max_value < @float.infinity, content="true")
inspect(@float.max_value > 0.0, content="true")
}let min_positive : Floattest {
inspect(@float.min_positive > 0.0, content="true")
inspect(@float.min_positive < 1.2e-38, content="true")
}let min_value : Floattest {
inspect(@float.min_value < -1.0, content="true")
inspect(@float.min_value > @float.neg_infinity, content="true")
}let neg_infinity : Floattest {
inspect(@float.neg_infinity.is_neg_inf(), content="true")
inspect(@float.neg_infinity < (-1.0 : Float), content="true")
}let not_a_number : Floattest {
inspect(@float.not_a_number.is_nan(), content="true")
inspect(@float.not_a_number + 1.0, content="NaN")
}Install
Installed by default