У меня вопрос о выполнении деления остатка целых чисел на C / C ++. Говорят, что при операции деления между двумя целыми числами, если результат не может быть выражен как целое число, его часть, которая не является целым числом, удаляется в десятичном виде. Например, int a = 17; а / = 3; / pseudo float a, получает значение 5,6666 .. /, поэтому результат равен 5. Это результат обычного деления с остатком в арифметике одновременно из-за части после точки (6666. .), который на самом деле является делением остатка (2) на 3. Это работает на моем компьютере, но действительно ли это надежно, или я должен объявить с помощью float, а затем преобразовать его в int с полом для безопасности? Что лучше с точки зрения производительности и безопасности? Заранее спасибо.
Определенность C ++ целочисленного деления с остатком
Ответы (3)
Арифметические операции с целыми числами в C ++ не зависят от компьютера.
Если a
и b
являются целыми числами, a / b
всегда будет давать вам целое частное от деления, а a % b
всегда будет давать вам остаток от целочисленного деления.
Что касается производительности, вы можете взглянуть на этот вопрос StackOverflow, но, похоже, он зависит от архитектуры.
Вы должны использовать a / b
и a % b
для целочисленного деления и остатка. Как говорит Леванс, они гарантированно дадут вам «правильные» значения независимо от вашего оборудования (по крайней мере, если a
и b
положительны). При арифметике с плавающей запятой на результат могут влиять ошибки округления, которые также могут зависеть от оборудования.
Итак, вместо целочисленного по модулю вы можете получить два числа с плавающей запятой, а затем умножить одно число с плавающей запятой на обратное к делителю:
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 раз медленнее, чем при использовании прямого модуля.
a % b
?
- person oseiskar; 14.07.2013
ceil
и floor
- это (не встроенные) вызовы функций, которые действительно займут некоторое время. Я на короткое время рассчитал это, попытавшись запустить total += i % mod;
и total += (int)ceil(i - floor(i * (1.0/mod)) * mod);
в цикле для всех i ‹1000000, и последнее было ок. В 14 раз медленнее.
- person oseiskar; 14.07.2013
mod
. В приведенном выше примере я использовал 12437788 (извините: я использовал i ‹100000000, а не один миллион)
- person oseiskar; 14.07.2013