Определенность C ++ целочисленного деления с остатком

У меня вопрос о выполнении деления остатка целых чисел на C / C ++. Говорят, что при операции деления между двумя целыми числами, если результат не может быть выражен как целое число, его часть, которая не является целым числом, удаляется в десятичном виде. Например, int a = 17; а / = 3; / pseudo float a, получает значение 5,6666 .. /, поэтому результат равен 5. Это результат обычного деления с остатком в арифметике одновременно из-за части после точки (6666. .), который на самом деле является делением остатка (2) на 3. Это работает на моем компьютере, но действительно ли это надежно, или я должен объявить с помощью float, а затем преобразовать его в int с полом для безопасности? Что лучше с точки зрения производительности и безопасности? Заранее спасибо.


person user2561614    schedule 14.07.2013    source источник


Ответы (3)


Арифметические операции с целыми числами в C ++ не зависят от компьютера.
Если a и b являются целыми числами, a / b всегда будет давать вам целое частное от деления, а a % b всегда будет давать вам остаток от целочисленного деления.

Что касается производительности, вы можете взглянуть на этот вопрос StackOverflow, но, похоже, он зависит от архитектуры.

person Levans    schedule 14.07.2013

Вы должны использовать a / b и a % b для целочисленного деления и остатка. Как говорит Леванс, они гарантированно дадут вам «правильные» значения независимо от вашего оборудования (по крайней мере, если a и b положительны). При арифметике с плавающей запятой на результат могут влиять ошибки округления, которые также могут зависеть от оборудования.

person oseiskar    schedule 14.07.2013

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

17.0 * 0.33 = 5.61

затем floor () в целое число и вычтите:

5.61 - 5 ----> 0.61

затем умножьте результат на значение, обратное 0,33:

0.61 * 3 ------> 1.83 

затем ceil () это

2    ----> this is 17%3

Согласно результатам тестирования пользователя Oseiskar, это в 14 раз медленнее, чем при использовании прямого модуля.

person huseyin tugrul buyukisik    schedule 14.07.2013
comment
что заставляет вас думать, что это быстрее или лучше, чем a % b? - person oseiskar; 14.07.2013
comment
Я сказал, что, возможно, его не жаловали. - person huseyin tugrul buyukisik; 14.07.2013
comment
Например, 65536% 255 могут составлять сотни циклов. Но здесь только пол, а функции потолка требуют времени. Остальные только умножение и вычитание. - person huseyin tugrul buyukisik; 14.07.2013
comment
в C ceil и floor - это (не встроенные) вызовы функций, которые действительно займут некоторое время. Я на короткое время рассчитал это, попытавшись запустить total += i % mod; и total += (int)ceil(i - floor(i * (1.0/mod)) * mod); в цикле для всех i ‹1000000, и последнее было ок. В 14 раз медленнее. - person oseiskar; 14.07.2013
comment
Какой был мод? Вы выбрали его достаточно большим и меньшим, чем я? Была ли это степень двойки? - person huseyin tugrul buyukisik; 14.07.2013
comment
результат практически не зависит от mod. В приведенном выше примере я использовал 12437788 (извините: я использовал i ‹100000000, а не один миллион) - person oseiskar; 14.07.2013
comment
Так что он всегда был меньше. Которая всегда прямо равна самой ценности. А с 255 тоже можно попробовать? - person huseyin tugrul buyukisik; 14.07.2013
comment
Я попробовал также 255, и результат не изменился. Также я хотел бы отметить, что ваш комментарий об отказе от использования констант в делениях также не имеет особого смысла, потому что компилятор, безусловно, автоматически выполнит такого рода оптимизацию. - person oseiskar; 14.07.2013
comment
Хорошо, спасибо за тестирование. Тогда я меняю ответ на твое имя. - person huseyin tugrul buyukisik; 14.07.2013