Почему деление на ноль для Float не вызывает исключения в Ruby? - PullRequest
5 голосов
/ 27 февраля 2020

Деление на ноль для Integer поднимает ZeroDivisionError:

0 / 0 # ZeroDivisionError

Однако деление на ноль для Float не делает:

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

Мне было интересно, почему есть эта разница в поведении для Integer и Float в Ruby?

1 Ответ

9 голосов
/ 27 февраля 2020

Как и почти во всех языках программирования, реализация ruby арифметики с плавающей точкой c соответствует стандарту IEEE 754 .

Эта спецификация (ссылка выше) определяет пять исключений, которые должны (по крайней мере по умолчанию) обрабатываться определенным образом c:

  • Недопустимая операция: математически не определена Например, квадрат root отрицательного числа. По умолчанию возвращает qNaN.

  • Деление на ноль: операция с конечными операндами дает точный бесконечный результат, например, 1/0 или log (0). По умолчанию возвращает ± бесконечность.

  • Переполнение: результат слишком велик для правильного представления (т. Е. Его показатель степени с неограниченным диапазоном показателей будет больше, чем emax). По умолчанию возвращает ± бесконечность для режимов округления до ближайшего (и следует правилам округления для режимов направленного округления).

  • Underflow: результат очень мал (вне нормы дальность) и неточно. По умолчанию возвращает субнормальное значение или ноль (в соответствии с правилами округления).

  • Неточно: точный (то есть необоснованный) результат не представляется точно. По умолчанию возвращает правильно округленный результат.

Поэтому 1.0/0 должно равняться +Infinity, а 0.0/0 должно равняться NaN.


Integer объекты не соответствуют вышеуказанному стандарту. (Не существует Infinity или NaN, и все операции являются точными.) Таким образом, c было принято решение о создании исключения для таких операций, как 1/0.

...