Какая альтернатива функции 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))
что это правильно?
Какая альтернатива функции 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))
что это правильно?
Не существует [простого] единственного определения lrint
, которое выполняет поведение, определенное стандартом C99. Это связано с тем, что поведение lrint
контролируется отдельными вызовами fesetround
. Вместо этого вы должны использовать отдельные функции округления с гарантированной семантикой для желаемого поведения вашего приложения.
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));
спасибо силикомарганца, исправленное, что .. –
@Insilico Код, он обеспечил первоначально работает, если 'fesetround (0)' был вызван до 'lrint'. Теперь он просто производит 0, если 'x> = 0', в противном случае -1. –
Я неправильно прочитал документацию - мне следовало написать 'fesetround (FE_TOWARDZERO)', а не 'fesetround (0)'. –