Skip to content

Specify: int->float and f32->f64 round to nearest, overflow to infinity #62231

Closed
@hanna-kruppe

Description

@hanna-kruppe

As suggested by @Centril, this issue is for getting @rust-lang/lang approval for rust-lang/reference#607 (Note: will update that patch to explicitly talk about overflow behavior, once approved here)

cc #62175

Detailed proposal

The following casts:

  • (expr: iM) as fN
  • (expr: uM) as fN
  • (expr: f64) as f32

all can see values that cannot be represented losslessly in the destination type, e.g.:

  • i32::MAX is not exactly representable as f32 (though it is less than f32::MAX, so it can be rounded to a finite float)
  • u128::MAX is larger than f32::MAX, so it cannot even be rounded to a nearby finite float (it "overflows")
  • f64 obviously has more precision than f32, so this cast has to round (infinities and NaNs can be carried over to f32, so this is only about finite numbers)

These cases are not unsound any more (see #15536), but currently the rounding mode is explicitly "unspecified" in the reference. What happens on overflow (e.g. u128::MAX as f32) is also not specified explicitly anywhere AFAICT. I proposed to define these casts as follows:

  • rounding mode: to nearest, ties to even (see IEEE 754-2008 §4.3.1)
  • on overflow: return infinity (with the sign of the source)

Rationale

Leaving the behavior of this core part of the language unspecified only hinders Rust programmers in using them and causes uncertainty and (de jure) non-portability. They should be defined as something, and I argue (round to nearest, overflow to infinity) is the most obvious, most consistent, and most useful choice:

  • IEEE 754-2008 prescribes round-to-nearest as the default rounding mode and returning (+/-) infinity as the default behavior on overflow (see §4.3.3, §7.4 in IEEE 754-2008).
  • This rounding mode and overflow behavior gives the closest possible result (which is of course why IEEE 754 makes it the default).
  • Other operations in Rust (e.g., string parsing) and conversions in other languages (e.g., Java) also default to these behaviors.
  • LLVM and hardware support this rounding mode and overflow handling natively, so it is also efficient.

Metadata

Metadata

Assignees

Labels

A-FFIArea: Foreign function interface (FFI)T-langRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions