# `@floatCast`

### `@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`.

```zig
const small: f32 = @floatCast(big);
```

This means:

```text
Convert big to f32.
```

The destination type comes from context.

#### A Simple Example

```zig
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:

```text
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:

```zig
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.

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

Zig can often allow this without an explicit `@floatCast`.

But narrowing usually needs a cast:

```zig
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:

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

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

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

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

```zig
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.

```zig
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`.

```zig
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.

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

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

```zig
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:

```zig
const y: f32 = @floatCast(x);
```

The type `f32` is written on the left side.

This also works:

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

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

#### A Practical Function

```zig
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:

```zig
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`:

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

Numerical code may use `f64` for better precision:

```zig
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.

