简体   繁体   中英

Does Rust f64/f32 round correctly?

After a recent discussion about mathematical rounding with my colleagues, we analyzed the rounding of different languages.

For example:

  • MATLAB: "Round half away from zero"
  • Python: "Round half to even"

I would not say the one is correct or the other isn't but whats bothers me is the combination of the writing in the Rust Book and what the documentation say about the round function.

The book 1 :

Floating-point numbers are represented according to the IEEE-754 standard. The f32 type is a single-precision float, and f64 has double precision.

The documentation 2 :

Returns the nearest integer to self. Round half-way cases away from 0.0.

My concern is that the standard rounding for IEEE-754 is "Round half to even".

Most collegues who I ask tend to use and learned mostly/only "Round half away from zero" and they where actually confused as I came up with different rounding strategies. Does the developer of rust decided because of that possible confusion against the IEEE standard?

Nobody has contradicted IEEE-754, which defines five different valid rounding methods .

The two methods relevant to this question are referred to as nearest roundings .

  • Round to nearest, ties to even – rounds to the nearest value; if the number falls midway, it is rounded to the nearest value with an even least significant digit.
  • Round to nearest, ties away from zero (or ties to away) – rounds to the nearest value; if the number falls midway, it is rounded to the nearest value above (for positive numbers) or below (for negative numbers).

Python takes the first approach and Rust takes the second. Neither is contradicting the IEEE-754 standard, which defines and allows for both.

The other three are things we would probably more colloquially refer to as truncation , ie always rounding down, or always rounding up, or always rounding toward zero.

The documentation you cite is for an explicit function, round .

IEEE-754 specifies the default rounding method for floating-point operations should be round-to-nearest, ties-to-even (with some embellishment for an unusual case). The rounding method specifies how to adjust (conceptually) the mathematical result of the function or operation to a number representable in the floating-point format. It does not apply to what functions functions calculate.

Functions like round , floor , and trunc exist to calculate a specific integer from the argument. The mathematical calculation they perform is to determine that integer. A rounding rule only applies in determining what floating-point result to return when the ideal mathematical result is not representable in the floating-point type.

Eg, sin(x) is defined to return a result computed as if:

  • The sine of x were determined exactly, with “infinite” precision.
  • That sine were then rounded to a number representable in the floating-point format according to the rounding method.

Similarly, round(x) can be thought of to be defined to return a result computed as if:

  • The nearest integer of x , rounding a half-way case away from zero, were determined exactly, with “infinite” precision.
  • That nearest integer were then rounded to a number representable in the floating-point format according to the rounding method.

However, because of the nature of the routine, that second step is never necessary: The nearest integer is always representable, so rounding never changes it. (Except, you could have abnormal floating-point formats with limited exponent range so that rounding up did yield an unrepresentable integer. For example, in a format with four-bit significands but an exponent range that limited numbers to less than 4, rounding 3.75 to the nearest integer would yield 4, but that is not representable, so +∞ would have to be returned. I cannot say I have ever seen this case explicitly addressed in a specification of the round function.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM