如何multiply/divide/add/subtract不同类型的号码?
How to multiply/divide/add/subtract numbers of different types?
我正在阅读 Rust 手册的第二版,并决定尝试制作经典的摄氏度到华氏度转换器:
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,令人惊讶的是,您不能简单地对不同类型的数字执行算术运算。像我在这里所做的那样,将它们简单地转换为同一类型是否正确?
TL;DR: as
是最常见的原始数值类型之间的转换方式,但使用它需要思考。
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.
}
真正的问题是做混合类型运算有点复杂
如果您将 1 a T
乘以 a T
,您通常希望得到 T
类型的结果,在至少是基本类型。
然而,当混合类型时,有一些困难:
- 混合签名,
- 混合精度。
那么,例如,i8 * u32
的理想结果是什么?可以包含所有 i8
和 u32
值的完整集合的最小类型是 i64
。应该是这样的结果吗?
再举个例子,f32 * i32
的理想结果是什么?可以包含所有 f32
和 i32
值的完整集合的最小类型是 f64
。应该是这样的结果吗?
我觉得有这样一个 加宽 的想法相当混乱。它还会对性能产生影响(f32
上的操作可以比 f64
上的操作快得多,一旦矢量化)。
由于这些问题,Rust 现在要求您明确说明:您希望在哪种类型中进行计算?哪种类型适合您的特定情况?
然后使用 as
进行适当的转换,并考虑应用哪种舍入模式(.round()
、.ceil()
、.floor()
或 .trunc()
当从浮点数变为整数时)。
1 加、减和除以类似的方式工作.
我正在阅读 Rust 手册的第二版,并决定尝试制作经典的摄氏度到华氏度转换器:
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,令人惊讶的是,您不能简单地对不同类型的数字执行算术运算。像我在这里所做的那样,将它们简单地转换为同一类型是否正确?
TL;DR: as
是最常见的原始数值类型之间的转换方式,但使用它需要思考。
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.
}
真正的问题是做混合类型运算有点复杂
如果您将 1 a T
乘以 a T
,您通常希望得到 T
类型的结果,在至少是基本类型。
然而,当混合类型时,有一些困难:
- 混合签名,
- 混合精度。
那么,例如,i8 * u32
的理想结果是什么?可以包含所有 i8
和 u32
值的完整集合的最小类型是 i64
。应该是这样的结果吗?
再举个例子,f32 * i32
的理想结果是什么?可以包含所有 f32
和 i32
值的完整集合的最小类型是 f64
。应该是这样的结果吗?
我觉得有这样一个 加宽 的想法相当混乱。它还会对性能产生影响(f32
上的操作可以比 f64
上的操作快得多,一旦矢量化)。
由于这些问题,Rust 现在要求您明确说明:您希望在哪种类型中进行计算?哪种类型适合您的特定情况?
然后使用 as
进行适当的转换,并考虑应用哪种舍入模式(.round()
、.ceil()
、.floor()
或 .trunc()
当从浮点数变为整数时)。
1 加、减和除以类似的方式工作.