Should `x / 0.` be an error?


#1

Rust panics when an integer is divided by zero, but seems to be fine with floating-point division by zero.

Is that deliberate? Could it—at least in debug mode—catch floating-point division by zero?

I’ve just had to fight infestation of NaNs in my program, and division by zero was the cause. An early panic would be useful.


#2

You want signalling NaNs.


#3

How can I enable them in Rust?


#4

Officially? No idea. But SNaNs are just marked by a particular bit-pattern, so you can probably insert them manually by just constructing them via a transmute… but I have no idea what will actually happen if they trigger a trap.

I was mostly just pointing out what the feature you were asking for was called.


#5

If it requires manual action then I’m afraid it doesn’t solve my problem of catching unexpected operations in unexpected places.


#6

The problem is that x / 0. is perfectly well-defined, and making them an error is just cutting off your nose to spite your face.

I’m saying that what you want is some way to switch on SNaNs. I have no idea if any other languages support this, or how they do it, but at least you know what they’re called now.


#7

The problem is that x / 0. is perfectly well-defined

IEEE 754 is awful :frowning: I wish there was a floating-point type (or mode of operation) in Rust that doesn’t adhere to IEEE 754 quirks.


#8

Well… the hardware Rust runs on doesn’t support other floating point types, so it would always need to be some software-impl… And that’s right where the num crate solves your problem: http://doc.rust-lang.org/num/num/rational/type.BigRational.html


#9

IEEE 754 is better than all alternatives, at least among fixed-width formats. This is more pronounced in other areas, but division by zero resulting in infinity is certainly not objectively terrible or a quirk: It works out splendidly for many numeric algorithms. I appreciate that you have no use for that behavior but please don’t make the mistake of extrapolating from that to all use cases.

Additionally, IEEE 754 provides traps/exceptions not only for illegal operations that would produce NaN, but also for division by zero, overflow, underflow, and even ordinary rounding errors. Most languages, including Rust, ignore that and offer no good way to use those capabilities, but that is not really the IEEE’s fault. Speaking of which… good support for floating point traps would be an easy and low-overhead way to check for division by zero when you care about it. I have no idea what “good support” would look like, though.


#10

I remember that D had quite a few serious numerical people using it. Based on a quick squiz at the docs, “good support” still amounts to “binding the fenv functions from C”. Well, that and I believe there’s a bit in the language spec about how changing the rounding mode within a function and then not restoring it before you leave is undefined behaviour.

I’m not trying to be derisive: this genuinely seems to be what “good support” is in a general purpose language.


#11

The C committee currently works on complete language support for IEEE 754 - ISO/IEC TS 18661 Floating-point extensions for C (Parts 1-5). Parts 1 and 2 are already published.
But I’m still curious, who is going to implement it and when.


#12

Fortran (from F2003 onwards) also has IEEE 754 support, but it doesn’t differ dramatically from what can be done in C99 IIRC. One difference is that if IEEE support is enabled, it requires the compiler to restore the rounding mode for you on exit from a function, rather than making it undefined behavior if you fail to restore it (but this obviously has some run-time overhead).