Какова правильная альтернатива функции C99 lrint в Windows?
#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)
будет правильно округлять только положительные числа, но не отрицательные, потому что floor () округляет в сторону отрицательной бесконечности, что означает, что floor (-7.1) = — 8, а фрагмент кода в кавычках не исправляет это: floor (-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));