floating-point - 为什么将整数添加到 float 时会出错?

标签 floating-point rust integer operators

我开始学习 Rust。我试过这个程序:

fn main() {
     let a = 5;
     let b = 5.5;
     let k = a + b;
     println!("{}", k);
}

它显示了这个错误:

error[E0277]: cannot add a float to an integer
 --> src/main.rs:4:16
  |
4 |      let k = a + b;
  |                ^ no implementation for `{integer} + {float}`
  |
  = help: the trait `std::ops::Add<{float}>` is not implemented for `{integer}`

代码有错吗?

最佳答案

技术上正确的答案是:因为没有人写过 impl Add<f64> for i32 {} .

厚颜无耻的回答是:因为 Rust 不希望你搬起石头砸自己的脚。

更长、可能更有用的答案是……

在计算机中,整数和 float 都有一个有限的范围,最终由我们用来表示它们的位数决定。在 Rust 中,不受其他约束的整数的默认类型是 i32 ,并且不受其他约束的浮点的默认类型是 f64 .

整数类型不允许你有小数部分,而浮点类型 have a limited number of integers they can exactly represent .如果 Rust 让您添加这两种类型,它会替您决定哪些数据不太重要,这并不是您真正希望系统编程语言做的事情!

以下是我可以看到的选项:

  1. 引发错误,迫使程序员选择他们需要的数据类型。
  2. 自动将两个数字转换为整数,丢弃任何可能的小数值。
  3. 自动将两个数字都转换为 float ,不正确地表示较大的整数值。

在这些选择中,只有一个错误是合理的。

还有可能引入一种可以精确处理任意精度的类型。不幸的是,这些类型对于处理器运行来说不再“廉价”,因此您必须权衡性能。

如果程序员希望执行一些转换,那么您可以使用 as 转换值或 From :

f64::from(a) + b;
a + b as i32 

另见:


Veedrac adds :

[this answer gives] the impression that 0u32 + 0u64 should work, but Rust doesn't do any numeric promotions, even if promotion would be lossless. Also, i32f64 is a lossless promotion, since f64 has a 52-bit mantissa.

虽然这些类型的扩大促销确实是无损的,但它们会隐含地增加您的内存需求。例如,过去只占用 32 位的内容现在占用 64 位。除了内存要求之外,还有语义方面的考虑。如果一个值应该只需要 u8 (0-255),那么将它增加一个可能超出该范围的值是没有意义的。知道进行这样的转换是否合适完全取决于程序员。

使用 From可以确保您只使用无损数字转换。

关于floating-point - 为什么将整数添加到 float 时会出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39677410/

相关文章:

c - c中的pow()函数使用什么算法

c - Pelles C 和 GCC 在这个 C 素性测试中给出了不同的结果

cross-compiling - 交叉编译时无法链接到核心库

rust - 为什么 Mutex 被设计为需要 Rust 中的 Arc

assembly - 无符号 64 位到 double 转换 : why this algorithm from g++

math - float 学有问题吗?

rust - 如何在没有借用检查器问题的情况下从函数返回新数据作为引用?

c# - “int” 和 “uint”/“long” 和 “ulong” 有什么区别?

ios - 如何在 Swift 2.0 中将 UITextField 转换为整数?

java - 为什么 Integer.parseInt ("11111111111111111111111111111111",2) 在 java 中抛出异常?