6

Dividing by zero for Integer raises a ZeroDivisionError:

0 / 0 # ZeroDivisionError

However dividing by zero for Float does not:

0.0 / 0   #NaN
0 / 0.0   #NaN
0.0 /0.0  #NaN    
1.0 / 0   #Infinity
1 / 0.0   #Infinity
1.0 /0.0  #Infinity

I was wondering why is there this difference in behaviour for Integer and Float in Ruby?

Boann
  • 48,794
  • 16
  • 117
  • 146
Nas
  • 1,063
  • 2
  • 9
  • 22
  • 7
    It's not Ruby-specific. It is the behavior defined in IEEE 754. Here is a good answer that provides some rationale: https://stackoverflow.com/a/14684474/8008340 – Konstantin Strukov Feb 27 '20 at 13:37

1 Answers1

10

As with almost all programming languages, ruby's implementation of floating-point arithmetic is compliant to the IEEE 754 standard.

This specification (linked above) defines five exceptions that must (at least by default) be handled in a specific way:

  • Invalid operation: mathematically undefined, e.g., the square root of a negative number. By default, returns qNaN.

  • Division by zero: an operation on finite operands gives an exact infinite result, e.g., 1/0 or log(0). By default, returns ±infinity.

  • Overflow: a result is too large to be represented correctly (i.e., its exponent with an unbounded exponent range would be larger than emax). By default, returns ±infinity for the round-to-nearest modes (and follows the rounding rules for the directed rounding modes).

  • Underflow: a result is very small (outside the normal range) and is inexact. By default, returns a subnormal or zero (following the rounding rules).

  • Inexact: the exact (i.e., unrounded) result is not representable exactly. By default, returns the correctly rounded result.

Therefore 1.0/0 must equal +Infinity, and 0.0/0 must equal NaN.


Integer objects do not conform to the above standard. (There is no Infinity or NaN, and all operations are exact.) Therefore, it was a language-specific decision to raise an exception for operations such as 1/0.

Tom Lord
  • 27,404
  • 4
  • 50
  • 77
  • 1
    Incidentally, you may also encounter some other "odd" behaviour in floating-point numbers, such as `Float::NAN == Float::NAN #=> false`. Once again, this is compliant with the IEEE 754 specification. – Tom Lord Feb 27 '20 at 13:57
  • 1
    The statement that these exceptions “must” be handled in a specific way may confuse readers. These results are the required results under default exception handling. Implementations may provide for alternate exception handling, which may, among other things, substitute any user-specified result. Also, this answer glosses over some of the details that trigger exceptions. – Eric Postpischil Feb 27 '20 at 19:37
  • 1
    Also, it should be noted that a “floating-point exception” is a case where the mathematical result is exceptional. It is not a C++ or Ruby type of exception that causes a change of program control (although a change of control may occur with alternate exception handling). – Eric Postpischil Feb 27 '20 at 19:38
  • @EricPostpischil I've edited my answer to say *(at least by default)* to be more accurate, thank you. And yes, I did gloss over some details around what constitutes an "exception" - but the original question only discussed `1/0` and `0/0`, which are quite straightforward scenarios. – Tom Lord Feb 28 '20 at 08:58