Инфраструктура .net включает Math.IEEERemainder (x, y) в дополнение к стандартному оператору модификации. Что на самом деле делает эта функция? Я не понимаю отрицательных чисел, которые это дает.
Пример:
Math.IEEERemainder(0, 2) = 0
Math.IEEERemainder(1, 2) = 1
Math.IEEERemainder(2, 2) = 0
Math.IEEERemainder(3, 2) = -1





Если вы прочитаете пример, приведенный в Страница MSDN System.Math.IEEERemainder, вы заметите, что два положительных числа могут иметь отрицательный остаток.
Return Value
A number equal to x - (y Q), where Q is the quotient of x / y rounded to the nearest integer (if x / y falls halfway between two integers, the even integer is returned).
Итак: 3 - (2 * (round (3/2))) = -1
/*
...
Divide two double-precision floating-point values:
1) The IEEE remainder of 1.797693e+308/2.00 is 0.000000e+000
2) The IEEE remainder of 1.797693e+308/3.00 is -1.000000e+000
Note that two positive numbers can yield a negative remainder.
*/
Фактический вопрос может быть таким: «Почему у нас есть две операции с остатком?» Когда имеешь дело с данные с плавающей запятой, вы всегда должны быть осведомлены о своем стандарте с плавающей запятой. Поскольку мы живем в 21 веке, почти все работает на IEEE 754, и очень немногие из нас беспокоятся о том, чтобы, скажем, VAX F_Float или IEEE 754.
Стандарт C# утверждает, что оператор остатка (раздел 7.7.3), когда он применяется к аргументам с плавающей запятой, аналогичен оператору остатка, когда применяется к целочисленным аргументам. То есть одна и та же математическая формула 1 используется (с дополнительными соображениями для угловых случаев, связанных с представлениями с плавающей запятой) как в операциях с целыми числами, так и в операциях с остатками с плавающей запятой.
Следовательно, если вы хотите, чтобы ваши операции с остатком для чисел с плавающей запятой соответствовали вашим текущим режимам округления IEEE 754, рекомендуется использовать Math.IEEERemainder. Однако, если ваше использование не особенно чувствительно к тонкой разнице в округлении, производимой оператором остатка C#, продолжайте использовать этот оператор.
@ffpf: ха-ха, интересно было бы, зачем вам Modulo и IEEERemainder. Можете обыграть меня, добавив это, если хотите: D
@sixlettervariables: Нет, я не спрашиваю. Боюсь ответа.
@ffpf: наслаждайтесь ответом, это не потрясающе.
Режимы округления IEEE 754 не влияют ни на операцию IEEERemainder, ни на операцию %, потому что оба они точны. Точность означает, что результат будет одинаковым независимо от режима округления. Что между ними различается, так это лежащее в основе понятие интегрального частного. IEEERemainder округляет математическое частное до ближайшего целого числа, чтобы получить q в x - q * y.
Вы говорите «почти все на IEEE 754», но я не понимаю, насколько это актуально, поскольку вопрос в том, почему C# (и большинство других языков) явно НЕ реализуют IEEE 754 для оператора модуля.
Это именно то, что я как раз собирался опубликовать. Уберись из моей головы. ;)