如何乘法/除/加/减不同类型的数字?

Ken*_*den 10 math arithmetic-expressions rust

我正在研究Rust手册的第二版,并决定尝试制作经典的Celsius-to-Fahrenheit转换器:

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9/5 ) ) + 32;
}
Run Code Online (Sandbox Code Playgroud)

编译cargo build它将产生编译时错误:

error[E0277]: the trait bound `f32: std::ops::Mul<{integer}>` is not satisfied
 --> src/main.rs:2:12
  |
2 |     return (c * (9 / 5)) + 32;
  |            ^^^^^^^^^^^^^ the trait `std::ops::Mul<{integer}>` is not implemented for `f32`
  |
  = note: no implementation for `f32 * {integer}`
Run Code Online (Sandbox Code Playgroud)

作为一个新的Rust程序员,我的解释是我不能将float和integer类型相乘.我通过使所有常量浮点数解决了这个问题:

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9.0/5.0 ) ) + 32.0;
}
Run Code Online (Sandbox Code Playgroud)

这让我有所保留.来自C/C++/Java/Python,令人惊讶的是,您不能简单地对不同类型的数字执行算术运算.正如我在这里做的那样简单地将它们转换为相同的类型是正确的吗?

Mat*_* M. 19

TL; DR:as是在原始数字类型之间进行转换的最常用方法,但使用它需要思考.

fn c_to_f(c: f32) -> f32 {
    (c * (9 as f32 / 5 as f32)) + 32 as f32
}
Run Code Online (Sandbox Code Playgroud)

但是在这个例子中,使用浮点文字开头更合理:

fn c_to_f(c: f32) -> f32 {
    (c * (9. / 5.)) + 32.
}
Run Code Online (Sandbox Code Playgroud)

真正的问题是,这样做混合型算术有点复杂.

如果你是乘1和一个TT,你通常希望得到类型的结果T,至少与基本类型.

但是,在混合类型时,存在一些困难:

  • 混合签名,
  • 混合精度.

那么,例如,理想的结果是i8 * u32什么?可以包含所有全部i8u32值的最小类型是a i64.这应该是结果吗?

再举一个例子,理想的结果是f32 * i32什么?可以包含所有全部f32i32值的最小类型是a f64.这应该是结果吗?

我发现这种扩大的想法相当令人困惑.它还具有性能影响(操作f32可以比操作更快f64,一旦矢量化).

由于存在这些问题,Rust现在要求您明确:您希望将计算带入哪种类型?哪种类型对您的特定情况有意义?

然后抹上适当地使用as,也考虑哪些入模式(适用.round(),.ceil(),.floor().trunc()从浮点到积分去的时候).

1 以类似的方式添加,减去和分割工作.

  • 因此,如果我想通过除法到 u128 来获得 f64,那么如何才能做到这一点而不首先将 u128 转换为 f64(因为它们会溢出)? (2认同)