Floats

Zig has the following floating point types:

  • f16 - IEEE-754-2008 binary16
  • f32 - IEEE-754-2008 binary32
  • f64 - IEEE-754-2008 binary64
  • f128 - IEEE-754-2008 binary128
  • c_longdouble - matches long double for the target C ABI

Float Literals

Float literals have type comptime_float which is guaranteed to have the same precision and operations of the largest other floating point type, which is f128.

Float literals coerce to any floating point type, and to any integer type when there is no fractional component.

float_literals.zig

  1. const floating_point = 123.0E+77;
  2. const another_float = 123.0;
  3. const yet_another = 123.0e+77;
  4. const hex_floating_point = 0x103.70p-5;
  5. const another_hex_float = 0x103.70;
  6. const yet_another_hex_float = 0x103.70P-5;
  7. // underscores may be placed between two digits as a visual separator
  8. const lightspeed = 299_792_458.000_000;
  9. const nanosecond = 0.000_000_001;
  10. const more_hex = 0x1234_5678.9ABC_CDEFp-10;

There is no syntax for NaN, infinity, or negative infinity. For these special values, one must use the standard library:

float_special_values.zig

  1. const std = @import("std");
  2. const inf = std.math.inf(f32);
  3. const negative_inf = -std.math.inf(f64);
  4. const nan = std.math.nan(f128);

Floating Point Operations

By default floating point operations use Strict mode, but you can switch to Optimized mode on a per-block basis:

foo.zig

  1. const std = @import("std");
  2. const big = @as(f64, 1 << 40);
  3. export fn foo_strict(x: f64) f64 {
  4. return x + big - big;
  5. }
  6. export fn foo_optimized(x: f64) f64 {
  7. @setFloatMode(.Optimized);
  8. return x + big - big;
  9. }

Shell

  1. $ zig build-obj foo.zig -O ReleaseFast

For this test we have to separate code into two object files - otherwise the optimizer figures out all the values at compile-time, which operates in strict mode.

float_mode.zig

  1. const print = @import("std").debug.print;
  2. extern fn foo_strict(x: f64) f64;
  3. extern fn foo_optimized(x: f64) f64;
  4. pub fn main() void {
  5. const x = 0.001;
  6. print("optimized = {}\n", .{foo_optimized(x)});
  7. print("strict = {}\n", .{foo_strict(x)});
  8. }

Shell

  1. $ zig build-exe float_mode.zig foo.o
  2. $ ./float_mode
  3. optimized = 1.0e-03
  4. strict = 9.765625e-04

See also: