iyi

Standard library, 0.18.0

std/float

Float32, made a number, and what Float64 still lacked.

import std/float to use it. Source: src/std/float.iyi at v0.18.0.

The prelude's float is Float64: 1.5, arithmetic, comparisons, floor, ceil, round, abs, ** and the shortest decimal that reads back as the same double. A Float32 literal, 1.5_f32, exists but had no method to land on. This module declares the @[Primitive] matrix for it the way the prelude does for Float64 - arithmetic, comparisons and conversions against every numeric type, instructions and nothing underneath - and gives it abs, floor, ceil, round, trunc, unary -, %, //, remainder, <=> (a total order, NaN last), nan?, infinite?, finite?, the constants NAN, INFINITY, MIN, MAX, EPSILON, MIN_POSITIVE, and a printer of its own: the shortest decimal that reads back as the same single, on the prelude's exact bignum, so 0.1_f32 prints 0.1 and Float32::MAX prints 3.4028235e+38. Float64 gets the same constants, trunc, unary -, %, //, remainder, <=> and the three predicates.

Mixed arithmetic answers the receiver's type, as the prelude's does: 1_u16 + 1.5_f32 is a Float32, 1.5 + 1.5_f32 a Float64, and 1.5_f32 + 1.5 a Float32 (computed in double, then narrowed). A single compared with an integer is compared exactly, on the double it is: 16777217 == 16777216.0_f32 is false.

% is the floored modulo, its sign the divisor's, as Float#% has meant where the name comes from, and so is the zero it answers: -0.0 % 1.0 is 0.0; remainder is the truncated one, its sign the dividend's; // is the floored quotient, so divmod answers what Python's does. All exact: no x - y * q that rounds. Either by zero panics "modulo by zero" or "division by zero". A conversion to an integer truncates and then refuses what the truncation does not hold ("arithmetic overflow"): 255.5_f32.to_u8 is 255, NaN and the infinities are refused. Narrowing a double to a single overflows to the infinity of its sign, as the single's own arithmetic does, and so does 2.0_f32 ** 128.

Float32struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Float32
  def !=(other : Float64) : Bool
  def !=(other : Float32) : Bool
  def !=(other : Int8) : Bool
  def !=(other : Int16) : Bool
  def !=(other : Int32) : Bool
  def !=(other : Int64) : Bool
  def !=(other : Int128) : Bool
  def !=(other : UInt8) : Bool
  def !=(other : UInt16) : Bool
  def !=(other : UInt32) : Bool
  def !=(other : UInt64) : Bool
  def !=(other : UInt128) : Bool
  # The floored modulo, the divisor's sign: `-7.5 % 2.0` is 0.5,
  # `7.5 % -2.0` is -0.5, and a zero takes the divisor's sign too -
  # `-0.0 % 1.0` is `0.0` - where it used to keep the dividend's.
  def %(other : Float32) : Float32
  def *(other : Int8) : self
  def *(other : Int16) : self
  def *(other : Int32) : self
  def *(other : Int64) : self
  def *(other : Int128) : self
  def *(other : UInt8) : self
  def *(other : UInt16) : self
  def *(other : UInt32) : self
  def *(other : UInt64) : self
  def *(other : UInt128) : self
  def *(other : Float64) : self
  def *(other : Float32) : self
  def **(exponent : Int32) : Float32
  def +(other : Int8) : self
  def +(other : Int16) : self
  def +(other : Int32) : self
  def +(other : Int64) : self
  def +(other : Int128) : self
  def +(other : UInt8) : self
  def +(other : UInt16) : self
  def +(other : UInt32) : self
  def +(other : UInt64) : self
  def +(other : UInt128) : self
  def +(other : Float64) : self
  def +(other : Float32) : self
  def -(other : Int8) : self
  def -(other : Int16) : self
  def -(other : Int32) : self
  def -(other : Int64) : self
  def -(other : Int128) : self
  def -(other : UInt8) : self
  def -(other : UInt16) : self
  def -(other : UInt32) : self
  def -(other : UInt64) : self
  def -(other : UInt128) : self
  def -(other : Float64) : self
  def -(other : Float32) : self
  # Multiplied rather than subtracted from zero, so `-(0.0)` is `-0.0`.
  def - : Float32
  def /(other : Float32) : Float32
  # The floored quotient, `divmod`'s other half: `7.5 // 2.0` is 3.0
  # and `-7.5 // 2.0` is -4.0. The exact remainder is taken off first
  # so the division is of a multiple of the divisor; it can still round,
  # so the quotient is floored and nudged up past a half. A zero
  # quotient has the sign of the division.
  #
  # A single's is the double's, narrowed. Run in 24 bits, `self - r`
  # can round once the quotient is past 2^23, and the division then
  # floored to the next integer: `-170277296.0_f32 // -13.303335_f32`
  # was 12799595.0 for 12799594.0, and `divmod`'s q * y + r missed x by
  # 13.3.
  def //(other : Float32) : Float32
  def <(other : Float64) : Bool
  def <(other : Float32) : Bool
  def <(other : Int8) : Bool
  def <(other : Int16) : Bool
  def <(other : Int32) : Bool
  def <(other : Int64) : Bool
  def <(other : Int128) : Bool
  def <(other : UInt8) : Bool
  def <(other : UInt16) : Bool
  def <(other : UInt32) : Bool
  def <(other : UInt64) : Bool
  def <(other : UInt128) : Bool
  def <=(other : Float64) : Bool
  def <=(other : Float32) : Bool
  def <=(other : Int8) : Bool
  def <=(other : Int16) : Bool
  def <=(other : Int32) : Bool
  def <=(other : Int64) : Bool
  def <=(other : Int128) : Bool
  def <=(other : UInt8) : Bool
  def <=(other : UInt16) : Bool
  def <=(other : UInt32) : Bool
  def <=(other : UInt64) : Bool
  def <=(other : UInt128) : Bool
  # A total order, so `Comparable` holds and a list of floats sorts:
  # NaN is after everything and equal to NaN. `<` and `==` keep IEEE's
  # answer, false against NaN; this is the one place NaN is placed.
  def <=>(other : Float32) : Int32
  def ==(other : Float64) : Bool
  def ==(other : Float32) : Bool
  # Against an integer, exact: on the double the single is exactly,
  # which holds every integer under 64 bits exactly too, and through
  # std/int's exact `<=>` for the wider ones, which the prelude's
  # `Int64 == Float64` agrees with. `16777217 == 16777216.0_f32` was true,
  # the integer rounded to a single first.
  def ==(other : Int8) : Bool
  def ==(other : Int16) : Bool
  def ==(other : Int32) : Bool
  def ==(other : Int64) : Bool
  def ==(other : Int128) : Bool
  def ==(other : UInt8) : Bool
  def ==(other : UInt16) : Bool
  def ==(other : UInt32) : Bool
  def ==(other : UInt64) : Bool
  def ==(other : UInt128) : Bool
  def >(other : Float64) : Bool
  def >(other : Float32) : Bool
  def >(other : Int8) : Bool
  def >(other : Int16) : Bool
  def >(other : Int32) : Bool
  def >(other : Int64) : Bool
  def >(other : Int128) : Bool
  def >(other : UInt8) : Bool
  def >(other : UInt16) : Bool
  def >(other : UInt32) : Bool
  def >(other : UInt64) : Bool
  def >(other : UInt128) : Bool
  def >=(other : Float64) : Bool
  def >=(other : Float32) : Bool
  def >=(other : Int8) : Bool
  def >=(other : Int16) : Bool
  def >=(other : Int32) : Bool
  def >=(other : Int64) : Bool
  def >=(other : Int128) : Bool
  def >=(other : UInt8) : Bool
  def >=(other : UInt16) : Bool
  def >=(other : UInt32) : Bool
  def >=(other : UInt64) : Bool
  def >=(other : UInt128) : Bool
  # Every single is a double, and the integer nearest a single is a
  # single: the prelude's `Float64` roundings are exact for it.
  # The sign cleared, by `Float64#abs`: a single widens to a double and
  # back exactly, and a comparison left `(-0.0_f32).abs` at `-0.0`.
  def abs : Float32
  def ceil : Float32
  def fdiv(other : Int8) : self
  def fdiv(other : Int16) : self
  def fdiv(other : Int32) : self
  def fdiv(other : Int64) : self
  def fdiv(other : Int128) : self
  def fdiv(other : UInt8) : self
  def fdiv(other : UInt16) : self
  def fdiv(other : UInt32) : self
  def fdiv(other : UInt64) : self
  def fdiv(other : UInt128) : self
  def fdiv(other : Float64) : self
  def fdiv(other : Float32) : self
  def finite? : Bool
  def floor : Float32
  def hash : Int32
  # 1 for +Infinity, -1 for -Infinity, nil for anything finite or NaN.
  def infinite? : Int32 | ::Nil
  def nan? : Bool
  # The remainder of the truncated division, the dividend's sign (C's
  # `fmod`), computed exactly: the divisor is doubled up to the dividend
  # and subtracted, and every such difference is exact.
  def remainder(other : Float32) : Float32
  def round(digits : Int32) : Float32
  def round(mode : Std::Number::RoundingMode) : Float32
  def round : Float32
  def to_f : Float64
  def to_f32 : Float32
  def to_f64 : Float64
  def to_i : Int32
  def to_i128 : Int128
  def to_i16 : Int16
  def to_i32 : Int32
  def to_i64 : Int64
  # Truncated first, then refused if the truncation does not fit:
  # `255.5_f32.to_u8` is 255 and `(-0.5_f32).to_u8` is 0. The instruction
  # is std/int's, on the double every single is exactly.
  def to_i8 : Int8
  def to_s : String
  def to_u : UInt32
  def to_u128 : UInt128
  def to_u16 : UInt16
  def to_u32 : UInt32
  def to_u64 : UInt64
  def to_u8 : UInt8
  # Toward zero. Past 2^24 every value is an integer already and is
  # answered as it is; NaN and the infinities likewise. A zero keeps the
  # sign of what was truncated - `(-0.5).trunc` is -0.0, as `floor` and
  # `ceil` answer - where the conversion through an integer lost it.
  def trunc : Float32
end

Float64struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Float64
  def !=(other : Float32) : Bool
  # The floored modulo, the divisor's sign: `-7.5 % 2.0` is 0.5,
  # `7.5 % -2.0` is -0.5, and a zero takes the divisor's sign too -
  # `-0.0 % 1.0` is `0.0` - where it used to keep the dividend's.
  def %(other : Float64) : Float64
  def *(other : Float32) : self
  def +(other : Float32) : self
  def -(other : Float32) : self
  # Multiplied rather than subtracted from zero, so `-(0.0)` is `-0.0`.
  def - : Float64
  # The floored quotient, `divmod`'s other half: `7.5 // 2.0` is 3.0
  # and `-7.5 // 2.0` is -4.0. The exact remainder is taken off first
  # so the division is of a multiple of the divisor; it can still round,
  # so the quotient is floored and nudged up past a half. A zero
  # quotient has the sign of the division.
  #
  # A single's is the double's, narrowed. Run in 24 bits, `self - r`
  # can round once the quotient is past 2^23, and the division then
  # floored to the next integer: `-170277296.0_f32 // -13.303335_f32`
  # was 12799595.0 for 12799594.0, and `divmod`'s q * y + r missed x by
  # 13.3.
  def //(other : Float64) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # A total order, so `Comparable` holds and a list of floats sorts:
  # NaN is after everything and equal to NaN. `<` and `==` keep IEEE's
  # answer, false against NaN; this is the one place NaN is placed.
  def <=>(other : Float64) : Int32
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def fdiv(other : Float32) : self
  def finite? : Bool
  # 1 for +Infinity, -1 for -Infinity, nil for anything finite or NaN.
  def infinite? : Int32 | ::Nil
  def nan? : Bool
  # The remainder of the truncated division, the dividend's sign (C's
  # `fmod`), computed exactly: the divisor is doubled up to the dividend
  # and subtracted, and every such difference is exact.
  def remainder(other : Float64) : Float64
  # The instruction, unchecked: a double past the single's range
  # narrows to the infinity of its sign, as `Float32::MAX * 2.0_f32`
  # answers. It used to panic "arithmetic overflow" here alone.
  def to_f32 : Float32
  # Toward zero. Past 2^53 every value is an integer already and is
  # answered as it is; NaN and the infinities likewise. A zero keeps the
  # sign of what was truncated - `(-0.5).trunc` is -0.0, as `floor` and
  # `ceil` answer - where the conversion through an integer lost it.
  def trunc : Float64
end

Int128struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Int128
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

Int16struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Int16
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

Int32struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Int32
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

Int64struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Int64
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

Int8struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::Int8
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

UInt128struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::UInt128
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

UInt16struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::UInt16
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

UInt32struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::UInt32
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

UInt64struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::UInt64
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end

UInt8struct, reopened

std/floatiyi doc src/std/float.iyi
struct ::UInt8
  def !=(other : Float32) : Bool
  def *(other : Float32) : Float32
  def +(other : Float32) : Float32
  def -(other : Float32) : Float32
  def /(other : Float32) : Float32
  # An integer over an integer is a double, as the other library
  # divides one, and written out so that an integer divisor matches
  # without a cast: beside `/(Float64)` and the `/(Float32)` above,
  # the literal in `7 / 2` cast to both, and importing this module
  # made that line "ambiguous call" where it had printed 3.5.
  def /(other : ::Int) : Float64
  def <(other : Float32) : Bool
  def <=(other : Float32) : Bool
  # The single's exact comparison, with the sides swapped.
  def ==(other : Float32) : Bool
  def >(other : Float32) : Bool
  def >=(other : Float32) : Bool
  def to_f32 : Float32
end