Например,
int result;
result = 125/100;
или
result = 43/100;
Результатом всегда будет пол дивизиона? Что такое определенное поведение?
"I just throw the dam fraction part in the trash and move on with life"
Например,
int result;
result = 125/100;
или
result = 43/100;
Результатом всегда будет пол дивизиона? Что такое определенное поведение?
"I just throw the dam fraction part in the trash and move on with life"
Ответы:
Результатом всегда будет пол дивизиона? Что такое определенное поведение?
Да, целочисленное отношение двух операндов.
6.5.5 Мультипликативные операторы
6 Когда целые числа делятся, результатом оператора / является алгебраический фактор с любой отброшенной дробной частью. 88) Если частное a / b представимо, выражение (a / b) * b + a% b должно быть равно a.
и соответствующая сноска:
88) Это часто называют усечением до нуля.
Конечно, следует отметить два момента:
3 Обычные арифметические преобразования выполняются над операндами.
и:
5 Результатом оператора / является частное от деления первого операнда на второй; результат оператора% - остаток. В обеих операциях, если значение второго операнда равно нулю, поведение не определено.
[Примечание: Акцент мой]
(a / b) * b + a % b == a
должны были быть выполнены, и абсолютное значение a % b
должно было быть меньше a
, но было ли a % b
отрицательным для отрицательного a
или b
не было указано.
Диркгентли дает отличное описание целочисленного деления в C99, но вы также должны знать, что в C89 целочисленное деление с отрицательным операндом имеет направление, определяемое реализацией.
Из проекта ANSI C (3.3.5):
Если любой из операндов отрицателен, то, является ли результат оператора / наибольшим целым числом, меньшим, чем алгебраическое частное, или наименьшим целым числом, большим, чем алгебраическое частное, определяется реализацией, как и знак результата оператора%. Если частное a / b представимо, выражение (a / b) * b + a% b должно быть равно a.
Так что следите с отрицательными числами, когда вы застряли с компилятором C89.
Это забавный факт, что C99 выбрал усечение до нуля, потому что именно так сделал это ФОРТРАН. Смотрите это сообщение на comp.std.c.
reliable integer division
как новая языковая функция. Удивительно *-*
.
expr1 / expr2
и expr1 % expr2
должно быть согласовано друг с другом, когда оба экземпляра expr1
объединяют одни и те же объекты одинаково, и аналогично expr2
, но выбор усечения по сравнению с разделением по этажам в противном случае не указан. Это позволило бы более эффективно генерировать код, не нарушая при этом большую совместимость (и реализации могли бы задокументировать конкретное поведение, если склонялись)
Там, где результат отрицательный, C усекается до 0, а не до пола - я узнал из этого прочтения о том, почему целочисленное деление Python всегда здесь: почему целочисленное деление этажей Python
filtered = (k - 1) * filtered + value + carry; carry = filtered % factor; filtered /= factor
повторяется с изменением значений value
. Это делает хорошее целочисленное приближение к фильтру нижних частот первого порядка с постоянной времени k
... но это только симметрично, если деление усекается и carry
получает отрицательные значения. Время от времени пригодятся оба способа разделения.
div
является операцией деления по полу и factor
является нечетным, то filtered += (filter+(factor div 2)) div factor
приведет к чистому и симметричному поведению для всех значений до INT_MAX-(factor div 2)
.
Да, результат всегда обрезается до нуля. Он округлится до наименьшего абсолютного значения.
-5 / 2 = -2
5 / 2 = 2
Для неподписанных и неотрицательных значений со знаком это то же самое, что и floor (округление в сторону -Infinity).
Результатом всегда будет пол дивизиона?
Нет. Результат варьируется, но изменение происходит только для отрицательных значений.
Что такое определенное поведение?
Чтобы было яснее, пол округляется в сторону отрицательной бесконечности, а целочисленное деление округляется до нуля (усекается)
Для положительных значений они одинаковы
int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0
Для отрицательного значения это отличается
int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0
Я знаю, что люди ответили на ваш вопрос, но с точки зрения непрофессионала:
5 / 2 = 2
// поскольку 5 и 2 являются целыми числами, а деление целых чисел всегда усекает десятичные дроби
5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5
// здесь либо 5, либо 2, либо оба имеют десятичную дробь, поэтому полученное вами значение будет в десятичной дроби.