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

时间:2017-06-14 18:34:49

标签: math rust arithmetic-expressions

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

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9/5 ) ) + 32;
}

使用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}`

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

fn c_to_f(c: f32) -> f32 {
    return ( c * ( 9.0/5.0 ) ) + 32.0;
}

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

1 个答案:

答案 0 :(得分:13)

TL; DR fn c_to_f(c: f32) -> f32 { (c * (9 as f32 / 5 as f32)) + 32 as f32 } 是在原始数字类型之间进行转换的最常用方法,但使用它需要思考。

fn c_to_f(c: f32) -> f32 {
    (c * (9. / 5.)) + 32.
}

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

T

真正的问题是混合型算术有点复杂。

如果您将{sup> 1 T乘以T,您通常希望获得i8 * u32类型的结果,至少是基本类型

然而,当混合类型时,存在一些困难:

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

那么,例如,i8的理想结果是什么?可以包含所有u32i64值的完整集合的最小类型是f32 * i32。这应该是结果吗?

另一个例子是f32的理想结果是什么?可以包含所有i32f64值的完整集合的最小类型是f32。这应该是结果吗?

我发现让这样的扩展相当混乱的想法。它也会产生性能影响(f64上的操作比as上的操作更快,一旦矢量化)。

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

然后使用.round()进行适当的投射,并考虑采用哪种舍入模式(.ceil().floor().trunc()或{{1}}从浮点到积分)。

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