Skip to content

`@floatCast`

@floatCast converts one floating-point value to another floating-point type.

@floatCast

@floatCast converts one floating-point value to another floating-point type.

You use it when changing between types such as f16, f32, f64, and f128.

const small: f32 = @floatCast(big);

This means:

Convert big to f32.

The destination type comes from context.

A Simple Example

const std = @import("std");

pub fn main() void {
    const x: f64 = 3.141592653589793;
    const y: f32 = @floatCast(x);

    std.debug.print("{}\n", .{y});
}

This converts a 64-bit float to a 32-bit float.

The result is close to the original value, but it may lose precision.

Floating-Point Types Have Different Precision

A larger floating-point type can usually represent more detail.

Common Zig floating-point types include:

f16   16-bit floating-point
f32   32-bit floating-point
f64   64-bit floating-point
f128  128-bit floating-point

When you cast from f64 to f32, the destination has fewer bits. Some detail may be rounded away.

Example:

const x: f64 = 1.0000000000000002;
const y: f32 = @floatCast(x);

The f32 value cannot keep the same precision as the f64 value.

Widening Is Usually Easier

Converting from f32 to f64 is usually safe in the sense that f64 has more precision and range.

const x: f32 = 1.5;
const y: f64 = x;

Zig can often allow this without an explicit @floatCast.

But narrowing usually needs a cast:

const x: f64 = 1.5;
const y: f32 = @floatCast(x);

The cast makes the possible precision loss visible.

@floatCast Is Not Integer Conversion

@floatCast converts between floating-point types only.

This is wrong:

const x: i32 = 42;
const y: f32 = @floatCast(x);

To convert an integer to a float, use @floatFromInt:

const x: i32 = 42;
const y: f32 = @floatFromInt(x);

To convert a float to an integer, use @intFromFloat:

const x: f32 = 42.0;
const y: i32 = @intFromFloat(x);

Use each builtin for the kind of conversion you actually mean.

Precision Loss

This is the main reason @floatCast matters.

const x: f64 = 123456789.123456789;
const y: f32 = @floatCast(x);

The f32 result cannot keep all the digits.

This does not mean the cast failed. It means the destination type has less precision.

For scientific computing, graphics, audio, physics, and simulations, this difference matters.

Range Loss

Floating-point types also have different ranges.

A very large f64 value may be too large for f32.

const x: f64 = 1.0e100;
const y: f32 = @floatCast(x);

The f32 type cannot represent that finite number.

Depending on the value and target behavior, the result may become infinity or otherwise follow floating-point conversion rules.

For ordinary beginner code, the important lesson is: casting to a smaller float type can lose precision, range, or both.

@floatCast vs @bitCast

Do not confuse these two.

@floatCast changes the numeric floating-point type while preserving the numeric value as closely as possible.

const x: f64 = 1.5;
const y: f32 = @floatCast(x);

@bitCast preserves the raw bits and changes the type interpretation.

const bits: u32 = @bitCast(@as(f32, 1.0));

Use @floatCast for numeric float conversion.

Use @bitCast only when you intentionally want representation-level behavior.

Destination Type Comes from Context

This works:

const y: f32 = @floatCast(x);

The type f32 is written on the left side.

This also works:

const y = @as(f32, @floatCast(x));

This is useful when the left side does not give Zig enough information.

A Practical Function

fn toF32(x: f64) f32 {
    return @floatCast(x);
}

This function clearly says: take an f64 and return an f32.

A more explicit name can be better in real code:

fn lossyToF32(x: f64) f32 {
    return @floatCast(x);
}

The word lossy reminds the reader that precision may be lost.

When Beginners Should Use It

Use @floatCast when an API expects a specific floating-point type.

For example, graphics libraries often use f32:

const x64: f64 = 12.5;
const x32: f32 = @floatCast(x64);

Numerical code may use f64 for better precision:

const rough: f32 = 0.1;
const precise: f64 = rough;

The choice of float type should be deliberate.

Key Idea

@floatCast converts one floating-point type to another.

It is mainly used when converting from a larger or more precise float type to a smaller one.

It preserves the numeric value as closely as the destination type allows, but precision or range may be lost.