- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
typedef int32_t wl_fixed_t;
//было:
static inline double wl_fixed_to_double(wl_fixed_t f)
{
return (double) f / 256.0;
}
//стало:
static inline double wl_fixed_to_double(wl_fixed_t f)
{
union {
double d;
int64_t i;
} u;
u.i = ((1023LL + 44LL) << 52) + (1LL << 51) + f;
return u.d - (3LL << 43);
}
+f - младшие биты мантиссы заполняем нашим числом
(1023LL+44LL)<<52 - порядок равен 2^44
Т.о. младшие 8 бит f попали в дробную часть, а старшие 44 в целую, но к ним прибавили 2^43 (та самая единичка сдвинутая на 51) и 2^44 - неявная единичка в виртуальном 53 бите мантиссы.
Нижняя строчка как раз корректирует это, вычитая 2^43*3 = 2^43+2^44.
P.S. мое описание для положительных чисел, для отрицательных пока не вкурил, но тем не менее код работает и для них.
UPD:
>int32_t
>2^44
Что-то тут не так...
И я, если что, только за Wayland. Вот только непонятно, как там с блобами жить.
on x86:
benchmarked magic: 14.048889885s
benchmarked mul: 4.034106976s
on x86-64:
benchmarked magic: 2.467789582s
benchmarked mul: 8.665307997s