2012-05-26 2 views
0

У меня есть регистр NEON, заполненный float32. Я бы хотел округлить их до ближайшего целого числа, не переходя к основному процессору. Инструкции NEON для преобразования float32 в uint32 просто обрезают, т.е. 39.7 будет 39, нет 40. Мне все равно, как обрабатывается 0.5 - округлите от нуля или круглый, чтобы даже обе работали для меня.Векторизованное округление с плавающей точкой с использованием NEON

Лучший путь я могу видеть, чтобы реализовать округление в

  • новообращенный int32 (таким образом, усечение)
  • конвертировать назад в float32
  • добавить 1 к int32, преобразовать обратно в float32 , и отложим в случае, если мы округляем
  • вычесть
  • по сравнению с 0.5 (нет необходимости значения абс, так как я знаю, в моем случае все они будут положительными)
  • выбрать усеченный или усеченной + 1 на основании результатов сравнения

Это кажется уродливым, медленно, и сложно.

Есть ли более чистый, быстрый, более простой и надежный способ?

ответ

5

Добавить .5 и преобразовать в целое число. Если вы хотите получить результат в формате с плавающей запятой, верните назад.

Поскольку вы знаете, что цифры все положительные, другой вариант - добавить 0x1p23 и вычесть 0x1p23. Результат добавления 0x1p23 составляет не менее 0x1p23, поэтому результат поплавка не имеет битов со значением меньше единицы, поэтому он должен быть округлен до целого. Затем вычитание 0x1p23 вычитает добавленное значение, оставив только эффект округления.

+0

Hahahaha. Я идиот. :) И спасибо за подсказку 0x1p23, это интересно. –

+0

Фактически, 0x1p23 приводит к некорректному результату, если вход находится в [0x1p47, 0x1p48), а его младший бит равен единице. Тогда 0x1p23 - половина ULP входа, поэтому добавление вызывает округление вверх (до четного), а вычитание не влияет. Я думаю, что есть возможность исправить это, но у меня его нет. –

+0

Я думаю, что значение, которое нужно добавить и вычесть, равно 0x1.8p + 23 – kanna

 Смежные вопросы

  • Нет связанных вопросов^_^