Преобразование Float32 в Float16

Это скорее продолжение https://stackoverflow.com/a/5587983/13586005. @sam hocevar или любой другой, кто это понимает: не могли бы вы объяснить, что здесь происходит:

tmp = (tmp - 0x70) & ((unsigned int)((int)(0x70 - tmp) >> 4) >> 27);

Я не уверен, что полностью его понимаю. Я понимаю, что (tmp - 0x70) исправляет смещение 127-> 15, но я не понимаю вторую часть ((unsigned int)((int)(0x70 - tmp) >> 4) >> 27) и, следовательно, не понимаю & с исправленным смещением на последнем шаге. Спасибо!


person prshnth23    schedule 25.05.2020    source источник


Ответы (1)


(unsigned int)((int)(0x70 - tmp) >> 4) >> 27

эквивалентен 1

(int)(0x70 - tmp) < 0 ? 0x1f : 0

но гарантированно не задействует ветвь - вместо этого он извлекает знаковый бит из результата извлечения, реплицирует его 4 раза, затем понижает передачу, чтобы получить либо 0x1f, либо 0 в зависимости.


1 В предположении, что сдвиги вправо со знаком отрицательных чисел делают правильный арифметический сдвиг - не гарантируемый спецификацией C, но общий для большинства реализаций

person Chris Dodd    schedule 25.05.2020