Skip to Content

Float

A literal with a decimal point belongs to the floating-point types (IEEE 754). Floats come in three widths: f16 (half precision), f32 (single precision, the default), and f64 (double precision). They compute fast and are the workhorses of graphics, games, and scientific computing; for exact decimal arithmetic use Decimal.

Literals

FormMeaning
1.5decimal form; no suffix means float32
1e10 / 1E-3 / 1.5e+2exponential notation
3.14f32 / 2.0f64 / 0.5f16explicit width suffixes (case-insensitive)
1f32 / 1.5e3f64no decimal point, or exponent with suffix — both legal
  • A digit must follow the decimal point: 1. and .5 are not floats.
  • The single-letter suffixes f / d / h do not exist; the full f16 / f32 / f64 is required.
  • There are no hexadecimal floats.

Display behavior

print prints the value, not padding: 2.0 prints as 2. f32 values render as the shortest round-trip string (0.1f32 prints as 0.1). Scientific notation kicks in past a width threshold — around 1e9 on the f32 side, around 1e16 on f64:

print(0.1f32); print(1e9); print(1e10); print(1f32, 1.5e3f64);
0.1 1E+09 1E+10 1 1500

Precision

Each precision computes in its own IEEE domain:

print(0.1 + 0.2); print(0.1 + 0.2 == 0.3); print(0.1f64 + 0.2f64); print(0.1f64 + 0.2f64 == 0.3f64); print(16777216f32 + 1);
0.3 True 0.30000000000000004 False 16777216
  • Bare decimals and f32 both compute in the single-precision domain: 0.1 + 0.2 == 0.3 is True because float32 rounding happens to cancel the two errors; f64 keeps more intermediate precision, which exposes the error (0.30000000000000004).
  • 16777216f32 + 1 rounds back to 16777216 under round-to-nearest-even: the 24-bit single-precision mantissa has no room for a 16777217th value.
  • Overflow gives ±∞, 0/0 gives NaN, and neither crashes.
  • When a suffixed literal is assigned to a wider target, it rounds at its own width first, then widens: val x: float64 = 0.3f16; gives 0.300048828125. A bare decimal has no width of its own and is taken directly at the target (val y: float64 = 0.3; gives 0.3).

Common functions

  • Floats also support ToString(format) formatting.
  • The Math module provides trigonometric functions, rounding, and the Pi / E constants.
  • Note that Math.Sqrt is a fallible function (square roots of negatives are a runtime error); here try? consumes the failure:
val x = 2.5; print(x.ToString("F1")); print(try? Math.Sqrt(4.0), try? Math.Sqrt(-1.0)); print(Math.Pi);
2.5 2 null 3.1415927

Notes

  • Implicit conversion and mixed arithmetic between floats and decimal are forbidden in both directions; convert explicitly with float64(x) / decimal64(x) (see Type Conversions);
  • Before comparing floats for equality, settle on an error budget, then decide between == and a tolerance comparison;
  • Numeric formatting output (fixed-point, percentages, and so on) is covered under Interpolation.
Last updated on October 11, 2026