округлить до нечетного или четного целого числа в C

Работая на языке Си, я хотел бы округлить число с плавающей точкой до его младшего нечетного целого числа и его младшего четного целого числа.
Скорость решения очень важна (потому что она вычисляется 2M * 20 раз в секунду).

Я предлагаю это решение:

x_even = (int)floor(x_f) & ~1;
x_odd  = ((int)ceil(x_f) & ~1) -1;

Я предполагаю, что слабым местом является floor а также ceil операции, но я даже не уверен в этом.

Есть ли у кого-то комментарий к этому решению; Меня интересует скорость выполнения, но если у вас есть другое решение, которым я могу поделиться, я буду очень рад его протестировать :-).

2

Решение

Вы не объясняете, что вы имеете в виду под «подчиненным», но предполагая, что вы имеете в виду «наибольшее четное / нечетное целое число меньше заданного числа», и предполагая, что у вас есть машина с дополнением 2s, вы хотите:

x_i = (int)floor(x_f);
x_even = x_i & ~1;
x_odd = x_i - (~x_i & 1);

Если вы хотите избежать зависимости реализации выполнения побитовых операций от, возможно, отрицательных чисел со знаком, вы можете вместо этого сделать это полностью в float:

x_even = 2.0 * floor(x_f * 0.5);
x_odd = x_even + 1.0 > x_f ? x_even - 1.0 : x_even + 1.0;

Это также имеет то преимущество, что не переполняется для больших чисел, хотя дает большие значения x_odd == x_even (слишком большие, чтобы представление с плавающей запятой представляло нечетное число).

0

Другие решения

Возможно, функции ceil и floor не понадобятся, поскольку значение transstypage от double до int эквивалентно функции floor для положительного целого числа.

Попробуйте что-то вроде этого для ПОЛОЖИТЕЛЬНЫХ ЦЕЛЕЙ:

double k = 68.8 ; // Because we need something to seed with.
int even  = ((int) k & ~1) ; // What you did
int test = ((int) (k+1) & ~1) ; // Little trick
int odd = (test>k) ? odd+1 : odd - 1 ;

Я проверил его на кодовой панели, и он хорошо работает на http://codepad.org/y3t0KgwW для C ++, я думаю, что будет в C. Если вы протестируете это решение, я был бы рад узнать, как быстро это может быть …

Заметить, что :

  • Это не очень хороший ответ, поскольку он скрывает существование отрицательных целых чисел.
  • Диапазон ограничен целыми числами.
  • Я поменялся нечетными и четными числами, я исправил это благодаря комментарию Криса.
  • Я просто добавляю свой скромный камень 🙂
0