Умножение отрицательных чисел с фиксированной точкой
У меня есть следующий метод умножения двух 32-битных чисел в фиксированной точке
Формат 19.13
. Но я думаю, что есть проблема с этим методом:
1.5f
округляется до 2.0f
, в то время как -1.5f
округляется до -1.0f
.
Мне кажется, что -1.5
следует округлить до -2.0f
.
Во-первых, имеет ли смысл текущее округление, и если нет, то как я могу его изменить быть более последовательным?
static OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
temp += 4096;
assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
return (OPJ_INT32) (temp >> 13);
}
1 ответ:
Поскольку вы всегда добавляете
4096
, код делает округление на полпути к положительной бесконечности. Это довольно странно.Чтобы округлить к положительной бесконечности, я бы ожидал
temp += 4096 + 4095;
Чтобы округлить обычным образом (до ближайшего), используйте вместо этого добавить смещение от 0.
temp += (temp < 0) ? -4096 : 4096;
Округлить до ближайших исвязей еще больше работы. Не уверен, что ОП этого хочет.