Не можете Mod Zero? - PullRequest
       15

Не можете Mod Zero?

55 голосов
/ 10 сентября 2011

Почему X % 0 неверное выражение?

Я всегда думал, что X % 0 должно равняться X. Поскольку вы не можете делить на ноль, разве ответ не должен быть естественным остатком, X (все осталось)?

Ответы [ 7 ]

39 голосов
/ 10 сентября 2011

Стандарт C ++ (2003) говорит в §5.6 / 4,

[...] Если второй операнд / или% равен нулю, поведение равно undefined ; [...]

То есть следующие выражения вызывают неопределенное поведение (UB):

X / 0; //UB
X % 0; //UB

Обратите внимание, что -5 % 2 НЕ равно -(5 % 2) (как Петр, кажется, предлагает в своем комментарии к своему ответу). Это определяется реализацией. В спецификации сказано (§5.6 / 4),

[...] Если оба операнда неотрицательны, то остаток неотрицателен; если нет, то знак остатка определяется реализацией .

10 голосов
/ 10 сентября 2011

Этот ответ не для математика. Этот ответ пытается дать мотивацию (за счет математической точности).

Математики: См. Здесь.

Программисты: Помните, что деление на 0 равно undefined. Следовательно, mod, который основан на делении, также undefined.


Это представляет собой деление на положительные X и D; он состоит из неотъемлемой части и дробной части:

(X / D) =   integer    +  fraction
        = floor(X / D) + (X % D) / D

Переставляя, вы получите:

(X % D) = D * (X / D) - D * floor(X / D)

Подставляя 0 для D:

(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)

Поскольку деление на 0 равно undefined:

(X % 0) = 0 * undefined - 0 * floor(undefined)
        = undefined - undefined
        = undefined
4 голосов
/ 10 сентября 2011

X % D по определению число 0 <= R < D, так что существует Q, так что

X = D*Q + R

Так что, если D = 0, такое число не может существовать (потому что 0 <= R < 0)

2 голосов
/ 10 сентября 2011

Еще один способ, который может быть концептуально прост для понимания вопроса:

На данный момент игнорируя вопрос знака аргумента, a % b можно легко переписать как a - ((a / b) * b). Выражение a / b не определено, если b равно нулю, поэтому в этом случае общее выражение тоже должно быть.

В конце концов модуль фактически является делительной операцией, поэтому, если a / b не определено, вполне разумно ожидать, что a % b также будет.

2 голосов
/ 10 сентября 2011

Я думаю, потому что, чтобы получить остаток от X % 0, вам нужно сначала вычислить X / 0, что дает бесконечность, и попытка вычислить остаток от бесконечности не представляется возможным.

Однако лучшее решениев соответствии с вашим мнением будет делать что-то вроде этого

REMAIN = Y ? X % Y : X
1 голос
/ 10 сентября 2011

X% Y дает результат в целочисленном диапазоне [0, Y). X% 0 должен был бы дать результат, больший или равный нулю, и меньше нуля.

0 голосов
/ 29 мая 2017

вы можете уклониться от случая «деления на 0» (A% B) для его идентификатора типа float (a, b) для float (B) = b = 0.0, который не определен или определяется по-разному между любыми 2реализации, чтобы избежать логических ошибок (жестких сбоев) в пользу арифметических ошибок ...

путем вычисления mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
вычисления mod([a],[b])

, где [a* b] == ваша ось x, со временем [b] == максимум кривой качания (которая никогда не будет достигнута) == первая производная функции качания

https://www.shadertoy.com/view/MslfW8

...