2013-03-10 3 views
2

Какая альтернатива функции lrint C99 в окнах?C++ Windows альтернатива lrint?

#define lrint(x) (floor(x+(x>0) ? 0.5 : -0.5)) 

/* and if fesetround(0) behavior is required*/ 

#define lrint(x) ((int)(x)) 

что это правильно?

+0

спасибо силикомарганца, исправленное, что .. –

+1

@Insilico Код, он обеспечил первоначально работает, если 'fesetround (0)' был вызван до 'lrint'. Теперь он просто производит 0, если 'x> = 0', в противном случае -1. –

+0

Я неправильно прочитал документацию - мне следовало написать 'fesetround (FE_TOWARDZERO)', а не 'fesetround (0)'. –

ответ

3

Не существует [простого] единственного определения lrint, которое выполняет поведение, определенное стандартом C99. Это связано с тем, что поведение lrint контролируется отдельными вызовами fesetround. Вместо этого вы должны использовать отдельные функции округления с гарантированной семантикой для желаемого поведения вашего приложения.

0
floor(x+(x>0) ? 0.5 : -0.5) 

будет правильно круглым только положительные числа, а не отрицательный, потому что пол() округляет в стороне отрицательной бесконечности, а это означает, что пол (-7.1) = - 8, а цитируемый фрагмент кода не устанавливает, что: пол (-7.1-0.5) = - 8, а правильное округление до ближайшего целого должно привести к -7. Следующий фрагмент кода делает правильное округление:

return int(x + ((x >= 0.0) ? 0.5 : -0.5)); 

В качестве альтернативы,

return ((x >= 0.0) ? floor(x+0.5) : ceil(x-0.5));