On Mon, 16 Jan 2023 14:43:43 +0800 "程安絮" <chenganxu2...@sina.com> wrote:
> In file main.go is my implementation of FixedToFloat64 vs > wl_fixed_to_double, the comments can help you to understand my codes. > Since event wl_touch::orientation's orientation arg is fixed value > and can be negative, I think this bug is not acceptable. Besides, I > don't understand how wl_fixed_to_double works, can anyone illustrate > that for me? > > --------------------------------程安絮 Hi, that wl_fixed_to_double() implementation in C is a far too smart trick for no other good reason than trying to be fast in a case where speed is not needed. The human readable conversion would be: double wl_fixed_to_double(wl_fixed_t f) { return (double)f / 256.0; } The trick code seems to be just fine through. I've attached a test program that iterates through all possible wl_fixed_t values and ensures the trivial conversion agrees with the trick conversion. I cannot explain how it works, but it does seem to work. Thanks, pq
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <stdbool.h> typedef int32_t wl_fixed_t; 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); } int main(void) { int32_t i = INT32_MIN; bool stop = false; do { wl_fixed_t f = i; double ref = (double)f / 256.0; double d = wl_fixed_to_double(f); if (ref != d) printf("%10d: %f != %f\n", f, ref, d); if (i % 100000000 == 0) printf("%10d: %f <-> %f\n", f, ref, d); stop = i == INT32_MAX; i++; } while (!stop); return 0; }
pgpVl9vtiLtJC.pgp
Description: OpenPGP digital signature