在Rust中将f64舍入到最近的i64

yon*_*ong 6 floating-point precision rust

Rust的f64类型提供了函数round(),它舍入到最接近的整数,但它返回一个f64.Math.round(double)另一方面,Java会返回一个long.我可以打电话round()然后再投i64,但这能保证我得到正确的结果吗?在这里,"正确"意味着获得最接近的i64- Java round()返回"最接近的长".

Chr*_*son 8

书中,从浮点到整数类型的转换向零舍入,因此首先舍入几乎是正确的:f.round() as i64.

但是,如果超出范围(巨大幅度),它目前也是未定义的行为(但这是一个错误).因此,您应该首先钳制该值(或者可能更好,引发错误或断言).可能明显的答案不起作用:f64i64

f.max(std::i64::MIN as f64).min(std::i64::MAX as f64).round() as i64
Run Code Online (Sandbox Code Playgroud)

因为i64::MAXto 的转换f64不准确,并且应用上述内容1e100最终会产生很大的负值(在我的测试中;如上所述它实际上是未定义的).

如果浮点值超出应用程序预期的合理范围,最好的选择似乎是返回一些错误.


DK.*_*DK. 7

你可以使用conv箱子:

use conv::prelude::*;

let x = 9_223_371_487_098_961_920i64 as f64;
println!("{:?}", x.approx_as_by::<i64, RoundToNearest>());
// Ok(9223371487098962944)

let x = 9_223_372_036_854_775_807i64 as f64;
println!("{:?}", x.approx_as_by::<i64, RoundToNearest>());
// Err(FloatError::PosOverflow(..))
Run Code Online (Sandbox Code Playgroud)