 # Integer division

Ok, here is another basic question:

let x = 7;
let y = 3

now, x / y gives 2… but this is wrong i want 2.333333

i find this way:

println!("{}", ((x1 as f64) / (x2 as f64)));

it seems to me a very poor way… is there another better?

Thx

2 Likes

You can declare the number type like so:

``````let x = 7f64;
let y = 3f64;

println!("{} / {} = {}", x, y, x/y);
``````

You could probably also use `let x = 7.0` in this case.

2 Likes

You did it right. Rust always prefer to be super explicit in the context of type conversion.

In the machine instructions, you can’t produce non-integer value from integer division. So as you want floating point value, you need floating point division instead. And finally, `x` and `y` variables you declared are integer types, so they must be converted to floating point types to perform floating point division.

2 Likes

Of course but the problem is another.
My starting point is that i’m working with integer type, because, for any reason my input data are integers. If, at any time in my project i have that kind of problem, that is making a trivial division and i want the real result, i found that workaround but it seems really bad.

thx.

I see. As Hyeonu says, you need to be explicit with types in Rust. You can make it look a bit neater by using an intermediate variable and omitting the brackets

``````let z = x as f64 / y as f64
``````

If you really don’t like to explicitly cast each time then you could write a simple utility function that takes (for example) two `i64`'s and returns an `f64`. Or perhaps a trait implemented on `i64` that does the same.

2 Likes

Better to try to minimize the number of “as” casts in your Rust programs:

``````fn main() {
let x: u32 = 7;
let y: u32 = 3;
println!("{}", f64::from(x) / f64::from(y));
}``````

Why? Is there some performance/data loss reason? What is different about `f64::from(x)` with regards to `x as f64`? I would think with `Copy` fundamental types, there should be no difference.

In general, the benefit of using `from` instead of `as` where possible is that it prevents bugs when refactoring - here’s a (somewhat contrived) example:

``````fn test(input: u8) {
let x = input as i32;
let y = i32::from(input);
}
``````

What happens if I later decide to change the type of `input` to `f32`?

• `x` silently gets truncated, because `as` can be a lossy operation.
• `y` throws a compile error, as the standard library does not implement `From` for lossy numeric conversions.

So that’s the main difference (and why Clippy nudges you to use the latter) - they don’t behave differently in this case, but it makes sure that the compiler will let you know if you accidentally change the behavior.

3 Likes

The docs state:

Note: this trait must not fail

It doesn’t mention anything about lossy conversions.

Ah, whoops, I misremembered that part! Have updated my post to take that info into account 