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? 

--------------------------------程安絮
package main

/*
double wl_fixed_to_double (unsigned int fix){
	union di {
		double d;
		long i;
	};

	union di u;

	u.i = ((1023L + 44L) << 52) + (1L << 51) + fix;

	return u.d - (3L << 43);
}
*/
import "C"
import (
	. "fmt"
	"unsafe"
)

func main() {
	var i uint64
	var n byte
	for i = 0; i < 0x100000000; i++ {
		fMy := MyFixedToFloat64(uint32(i))

		fWl := float64( C.wl_fixed_to_double( C.uint(i) ) )

		if fMy != fWl {
			Printf("i: %X\nfMy: %x\nfWl: %x\n", i, fMy, fWl)
			n++
			if n==5{break}
		}
	}

} //main

func MyFixedToFloat64(fix uint32) float64 {


	// fixed value have 1 sign bit and 31 value bits
	// decimal point between bit9 and bit8(right to left index order, start at 1)

	// get sign bit
	var sign uint64 = uint64( fix&0x80000000 )<<32

	// shift out 1 sign bit, pad 1 value bit of `0` on right side, value bits increase to 32
	// decimal point and value bits move together(1bit left), don't change the value;
	// decimal point between bit10 and bit9
	fixValue:=fix<<1

	// if value is zero
	// then return float64 value should be `+0` or `-0`, depends on the sign bit
	if fixValue == 0 {
		// wayland use "Native Byteorder", so no need to worry about byte-endian
		// just use pointer convertion to convert bits to float64 value
		return *(*float64)(unsafe.Pointer(&sign) )
	}


	// shift out all successive `0`s on the left side and save number of zeros shifted out in `n0`
	// the most left `1` will be the hidden bit of Fraction, should be shifted out too
	// shift out n0 bits of `0` and 1 bit of `1` on left, pad in n0+1 bits of `0` on the right, so number of value bits is still 32
	// decimal point and value bits move together(n0+1bits left), don't change the value;
	// decimal point between bit(n0+1+10) and bit(n0+1+9) i.e bit(n0+11) and bit(n0+10)
	var n0 uint64
	for {
		if fixValue&0x80000000 != 0 {
			fixValue <<=1
			break
		}
		fixValue <<= 1
		n0++
	} //for

	// float64 have 52 Fraction bits, fixValue only have 32 bits
	// so fixValue should be convert to uint64 and shift left 20 bits(pad 20bits of `0` on the right side)
	// decimal point and value bits move together(20bits left), don't change the value;
	// decimal point between bit(20+n0+11) and bit(20+n0+10) i.e bit(31+n0) and bit(30+n0)
	var frac uint64 = uint64(fixValue) << 20

	// float64's decimal point between bit53 and bit 52
	// so float64's decimal point should move 52-(30+n0)bits right i.e (22-n0)bits right
	// move decimal point right equals to increase exponent, so exponent should increase by 22-n0
	// float64's exponent Biased up by 1023, so exponent should be 1023+22-n0 i.e 1045-n0
	// shift left 52bits put exponent at the correct place
	var exp uint64 = (1045 - n0) << 52

	// `or` sign, exponent and fraction together, get the float64bits
	fBits := sign | exp | frac

	// pointer convert float64bits to float64 value
	return *(*float64)(unsafe.Pointer(&fBits))
} // func

Reply via email to