Целочисленное деление округляется в C # (для негативов) - PullRequest
1 голос
/ 16 марта 2019

Есть ли способ выполнить целочисленное деление в C # (без числа с плавающей или десятичной дробью, мне нужно сохранить это очень быстро), которое округляет число?

Деление по умолчанию просто отбрасывает аргумент дроби.Рассмотрим:

 1 / 2 = 0 // That is correct
-1 / 2 = 0 // ... but I want to get (-1) here!

Мое деление будет принимать положительные и отрицательные числа для делителя.Мне не нужно использовать if, так как ветвление будет слишком дорогим (операция будет выполняться очень часто в игровом движке реального времени) ...

Ответы [ 2 ]

2 голосов
/ 16 марта 2019

Деление на 2 является простым побитовым сдвигом вправо. После упоминания @ elgonzo (теперь удаленного) о свойствах смещения прав в C # я решил посмотреть, как это работает, и кажется, что делает именно то, что вы хотите:

var result = number >> 1;

Это дает следующие результаты:

11 -> 5
10 -> 5
2 -> 1
1 -> 0
-1 -> -1
-2 -> -1
-32 -> -16
-33 -> -17

int.MaxValue и MinValue также работают.

С точки зрения производительности, это, кажется, почти в два раза быстрее, чем принятый в настоящее время ответ, который использует операторы по модулю. Разделение (одинаковое) 100000000 случайных чисел на моей машине стоит 2,17 секунды, используя простую смену, в то время как использование версии с модулями занимает от 3,1 до 4,0 секунд.

Похоже, что разветвленные версии работают примерно так же, как версия по модулю: значительно медленнее, чем простое смещение прав.

2 голосов
/ 16 марта 2019

Если вы хотите разделить a на b:

Подход, который не потерпит неудачу из-за переполнения:

int res = a / b;
return (a < 0 && a != b * res) ? res - 1 : res;

Следующие подходы могут быть неудачными из-за отрицательного переполнения.

int mod = a % b;
if (mod < 0) {
  mod += b;
}
return (a - mod) / b;

Беспорядок с mod += b, потому что a % b может быть отрицательным. Более короткий путь:

return (a - (a % b + b) % b) / b;

И еще более понятный:

return a >= 0 ? a / b : (a - b + 1) / b;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...