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;
}

Attachment: pgpVl9vtiLtJC.pgp
Description: OpenPGP digital signature

Reply via email to