Is this a bug?

src/main.zig:30:26: error: @intFromFloat must have a known result type
        const x: usize = @intFromFloat(@sqrt(@as(f64, @floatFromInt(rad * rad - y * y)))) * ratio;
src/main.zig:30:26: note: use @as to provide explicit result type

This compiles just fine without * ratio, but complains with. I don’t think this is correct behaveior, am I right in thinking so?


const x: usize = @intFromFloat(@sqrt(@as(f64, @floatFromInt(rad * rad - y * y))));

You’re simply assigning the result of intFromFloat to x so the type can be inferred where as with:

const x: usize = @intFromFloat(@sqrt(@as(f64, @floatFromInt(rad * rad - y * y)))) * ratio;

The resulting type is actually apart of an operation and has nothing to be inferred as. I’m not sure if there’s any plans to have the compiler walk out the operations to try to determine the outermost type, but I doubt it as that could lead to many bugs. The new inference in general is already on the edges of Zigs typical explicitness.

I would split the line up into something like (with names instead of letters):

const a: f64 = @floatFromInt(rad * rad - y * y);
const b: usize = @intFromFloat(@sqrt(a));
const c = b * ratio;

Avoids using @ as everywhere and makes it easier to reason about when you have a type cast on a new line

1 Like

Okay I see. Man I love zig but working with numbers is incredibly unpleasant

1 Like

It’s definitely different, especially when coming from languages that do most (if not all) of the numeric casting for you

I’m not sure how long you’ve been using Zig, but at least for me, I’ve learned to really appreciate most of the things I didn’t enjoy at first. Once I really got a grasp of the language and some of it’s quirks I’ve found I’m writing much cleaner code and running into fewer bugs. The core team and other contributors have put a ton of thought and reasoning behind each decision and are still adding to/adjusting the language as they work towards a 1.0 release


100% agree, in fact im wondering if making casting so verbose is to prevent you from doing this too much as it might have a performance cost im not aware of, thats just speculation rn though

Ive played around in goldbolt a bit and at least casting from float to int seems to be a giant block of assembly, but my knowledge about assembly isnt deep enough to make any real judgement

Casting shouldn’t have almost any performance hit to it, it’s the operations on the value and the memory used that starts to add up. An operation on a u32 generally takes less instructions than the same operation on an f64

Do you mind sharing the godbolt link and I might be able to explain a bit better what’s going on?

I think you probably just forgot to compile in release-fast, in debug/release-safe there will be a ton of safety checks from float to integer(range checks, NaN checks). Integer to float on the other hand doesn’t require any safety checks.
For me it always is just a single instruction in release: Compiler Explorer


Nvm you guys were right, I accidently got the releaseoptions wrong, the upper link has them incorrectly

kinda wish zig would warn someone in this case

*freaked out Ziggy* you commented out some lines, and now some of your variables are unused
*chef’s kiss Ziggy* you passed nonsense arguments to the compiler


lmao my fault :grimacing: