d3dx9: Implement D3DXFloat32To16Array and D3DXFloat16To32Array. (try 2)
Misha Koshelev
misha680 at gmail.com
Sat Feb 26 19:50:02 CST 2011
On Sat, Feb 26, 2011 at 4:48 PM, Juan Lang <juan.lang at gmail.com> wrote:
> Hi Misha,
>
>> My own (very unhelpful) diagnosis of the pattern is that, for the
>> mantissa values:
>>
>> 2018.5 should round to 2018
>> 2019.5 should round to 2020
>
> The pattern appears to be "round half to even", which you may read
> about on Wikipedia:
> http://en.wikipedia.org/wiki/Rounding#Round_half_to_even
> --Juan
>
Thanks Juan. I have implemented this in the patch.
I am, unfortunately, still pretty stumped. There are quite a few cases
per Matteo's wonderful rounding code for truncation of very small (?)
numbers where rounding should _not_ occur.
I have included relevant output from running make math.ok for those cases.
Note, that it is not the specific mantissa #'s per se (I checked), not
even combinations of mantissa #'s and exp's, and not mantissa #'s and
exp's and <= 0.25f difference between ((unsigned int) tmp) and
(((unsigned int) tmp) & 0x3ff) - I checked all these.
There is apparently some pattern in the original single #'s themselves
that I am not seeing.
If anyone has a keener eye than I let me know.
Also, I am assuming a stub of this function would actually not be
accepted into Wine (can't return E_NOTIMPL, e.g.).
If I am _incorrect_ about this please let me know.
Thank you. Have a great Saturday!
Misha
-------------- next part --------------
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index f91f962..28259bc 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -130,8 +130,8 @@
@ stub D3DXFillVolumeTextureTX
@ stdcall D3DXFilterTexture(ptr ptr long long)
@ stdcall D3DXFindShaderComment(ptr long ptr ptr)
-@ stub D3DXFloat16To32Array
-@ stub D3DXFloat32To16Array
+@ stdcall D3DXFloat16To32Array(ptr ptr long)
+@ stdcall D3DXFloat32To16Array(ptr ptr long)
@ stub D3DXFrameAppendChild
@ stub D3DXFrameCalculateBoundingSphere
@ stub D3DXFrameDestroy
diff --git a/dlls/d3dx9_36/math.c b/dlls/d3dx9_36/math.c
index fdb5f92..6f8a71d 100644
--- a/dlls/d3dx9_36/math.c
+++ b/dlls/d3dx9_36/math.c
@@ -1769,3 +1769,123 @@ D3DXVECTOR4* WINAPI D3DXVec4TransformArray(D3DXVECTOR4* out, UINT outstride, CON
}
return out;
}
+
+static inline unsigned short float_32_to_16(const float in)
+{
+ int exp = 0, origexp;
+ float tmp = fabs(in);
+ int sign = signbit(in);
+ unsigned int mantissa;
+ unsigned short ret;
+
+ /* Deal with special numbers */
+ if (isinf(in)) return (sign ? 0xffff : 0x7fff);
+ if (isnan(in)) return (sign ? 0xffff : 0x7fff);
+ if (in == 0.0f) return (sign ? 0x8000 : 0x0000);
+
+ if (tmp < powf(2, 10))
+ {
+ do
+ {
+ tmp = tmp * 2.0f;
+ exp--;
+ } while (tmp < powf(2, 10));
+ }
+ else if (tmp >= powf(2, 11))
+ {
+ do
+ {
+ tmp /= 2.0f;
+ exp++;
+ } while (tmp >= powf(2, 11));
+ }
+
+ exp += 10; /* Normalize the mantissa */
+ exp += 15; /* Exponent is encoded with excess 15 */
+
+ origexp = exp;
+
+ mantissa = (unsigned int) tmp;
+ if ((tmp - mantissa == 0.5f && mantissa % 2 == 1) || /* round half to even */
+ (tmp - mantissa > 0.5f)) mantissa++; /* round to nearest, away from zero */
+ if (mantissa == 2048)
+ {
+ mantissa = 1024;
+ exp++;
+ }
+
+ if (exp > 31)
+ {
+ /* too big */
+ ret = 0x7fff; /* INF */
+ }
+ else if (exp <= 0)
+ {
+ unsigned int rounding = 0;
+
+ exp = origexp;
+
+ /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers */
+ mantissa = (unsigned int) tmp;
+ mantissa &= 0x3ff;
+ mantissa |= 0x400; /* explicit the first bit */
+ while (exp <= 0)
+ {
+ rounding = mantissa & 1;
+ mantissa >>= 1;
+ exp++;
+ }
+ ret = mantissa + rounding;
+ }
+ else
+ {
+ ret = (exp << 10) | (mantissa & 0x3ff);
+ }
+
+ ret |= ((sign ? 1 : 0) << 15); /* Add the sign */
+ return ret;
+}
+
+D3DXFLOAT16 *WINAPI D3DXFloat32To16Array(D3DXFLOAT16 *pout, CONST FLOAT *pin, UINT n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; ++i)
+ {
+ pout[i].value = float_32_to_16(pin[i]);
+ }
+
+ return pout;
+}
+
+/* Native d3dx9's D3DXFloat16to32Array lacks support for NaN and Inf. Specifically, e = 16 is treated as a
+ * regular number - e.g., 0x7fff is converted to 131008.0 and 0xffff to -131008.0. */
+static inline float float_16_to_32(const unsigned short in)
+{
+ const unsigned short s = (in & 0x8000);
+ const unsigned short e = (in & 0x7C00) >> 10;
+ const unsigned short m = in & 0x3FF;
+ const float sgn = (s ? -1.0f : 1.0f);
+
+ if (e == 0)
+ {
+ if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
+ else return sgn * powf(2, -14.0f) * ((float)m / 1024.0f);
+ }
+ else
+ {
+ return sgn * powf(2, (float)e - 15.0f) * (1.0f + ((float)m / 1024.0f));
+ }
+}
+
+FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, CONST D3DXFLOAT16 *pin, UINT n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; ++i)
+ {
+ pout[i] = float_16_to_32(pin[i].value);
+ }
+
+ return pout;
+}
diff --git a/dlls/d3dx9_36/tests/math.c b/dlls/d3dx9_36/tests/math.c
index 5ad1924..8a79893 100644
--- a/dlls/d3dx9_36/tests/math.c
+++ b/dlls/d3dx9_36/tests/math.c
@@ -21,6 +21,7 @@
#include "wine/test.h"
#include "d3dx9.h"
+#include <math.h>
#define ARRAY_SIZE 5
@@ -2215,6 +2216,337 @@ static void test_D3DXVec_Array(void)
compare_planes(exp_plane, out_plane);
}
+#define INT16_TYPE short
+#define UINT16_TYPE unsigned short
+#define INT32_TYPE long
+#define UINT32_TYPE unsigned long
+
+int singles2halfp(void *target, void *source, int numel)
+{
+ UINT16_TYPE *hp = (UINT16_TYPE *) target; // Type pun output as an unsigned 16-bit int
+ UINT32_TYPE *xp = (UINT32_TYPE *) source; // Type pun input as an unsigned 32-bit int
+ UINT16_TYPE hs, he, hm;
+ UINT32_TYPE x, xs, xe, xm;
+ int hes;
+ static int next; // Little Endian adjustment
+ static int checkieee = 0; // Flag to check for IEEE754, Endian, and word size
+ double one = 1.0; // Used for checking IEEE754 floating point format
+ UINT32_TYPE *ip; // Used for checking IEEE754 floating point format
+
+ if( checkieee ) { // 1st call, so check for IEEE754, Endian, and word size
+ ip = (UINT32_TYPE *) &one;
+ if( *ip ) { // If Big Endian, then no adjustment
+ next = 0;
+ } else { // If Little Endian, then adjustment will be necessary
+ next = 1;
+ ip++;
+ }
+ if( *ip != 0x3FF00000u ) { // Check for exact IEEE 754 bit pattern of 1.0
+ return 1; // Floating point bit pattern is not IEEE 754
+ }
+ if( sizeof(INT16_TYPE) != 2 || sizeof(INT32_TYPE) != 4 ) {
+ return 1; // short is not 16-bits, or long is not 32-bits.
+ }
+ checkieee = 0; // Everything checks out OK
+ }
+
+ if( source == NULL || target == NULL ) { // Nothing to convert (e.g., imag part of pure real)
+ return 0;
+ }
+
+ while( numel-- ) {
+ x = *xp++;
+ if( (x & 0x7FFFFFFFu) == 0 ) { // Signed zero
+ *hp++ = (UINT16_TYPE) (x >> 16); // Return the signed zero
+ } else { // Not zero
+ xs = x & 0x80000000u; // Pick off sign bit
+ xe = x & 0x7F800000u; // Pick off exponent bits
+ xm = x & 0x007FFFFFu; // Pick off mantissa bits
+ if( xe == 0 ) { // Denormal will underflow, return a signed zero
+ *hp++ = (UINT16_TYPE) (xs >> 16);
+ } else if( xe == 0x7F800000u ) { // Inf or NaN (all the exponent bits are set)
+ if( xm == 0 ) { // If mantissa is zero ...
+ *hp++ = (UINT16_TYPE) ((xs >> 16) | 0x7fffu); // Signed Inf
+ } else {
+ *hp++ = (UINT16_TYPE) 0xFfffu; // NaN, only 1st mantissa bit set
+ }
+ } else { // Normalized number
+ hs = (UINT16_TYPE) (xs >> 16); // Sign bit
+ hes = ((int)(xe >> 23)) - 127 + 15; // Exponent unbias the single, then bias the halfp
+ if( hes >= 0x1F ) { // Overflow
+ *hp++ = (UINT16_TYPE) ((xs >> 16) | 0x7fffu); // Signed Inf
+ } else if( hes <= 0 ) { // Underflow
+ if( (14 - hes) > 24 ) { // Mantissa shifted all the way off & no rounding possibility
+ hm = (UINT16_TYPE) 0u; // Set mantissa to zero
+ } else {
+ xm |= 0x00800000u; // Add the hidden leading bit
+ hm = (UINT16_TYPE) (xm >> (14 - hes)); // Mantissa
+ if( (xm >> (13 - hes)) & 0x00000001u ) // Check for rounding
+ hm += (UINT16_TYPE) 1u; // Round, might overflow into exp bit, but this is OK
+ }
+ *hp++ = (hs | hm); // Combine sign bit and mantissa bits, biased exponent is zero
+ } else {
+ he = (UINT16_TYPE) (hes << 10); // Exponent
+ hm = (UINT16_TYPE) (xm >> 13); // Mantissa
+ if( xm & 0x00001000u ) // Check for rounding
+ *hp++ = (hs | he | hm) + (UINT16_TYPE) 1u; // Round, might overflow to inf, this is OK
+ else
+ *hp++ = (hs | he | hm); // No rounding
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+const char *int_to_binary
+(
+ int x
+ )
+{
+ static char b[100];
+ int i = 0;
+ b[0] = '\0';
+
+ int z;
+ for (z = 32768; z > 0; z >>= 1, i++)
+ {
+ strcat(b, ((x & z) == z) ? "1" : "0");
+ }
+
+ return b;
+}
+
+static inline unsigned short float_32_to_16(const float in)
+{
+ int exp = 0, origexp;
+ float tmp = fabs(in);
+ int sign = signbit(in);
+ unsigned int mantissa;
+ unsigned short ret;
+
+ /* Deal with special numbers */
+ if (isinf(in)) return (sign ? 0xffff : 0x7fff);
+ if (isnan(in)) return (sign ? 0xffff : 0x7fff);
+ if (in == 0.0f) return (sign ? 0x8000 : 0x0000);
+
+ if (tmp < powf(2, 10))
+ {
+ do
+ {
+ tmp = tmp * 2.0f;
+ exp--;
+ } while (tmp < powf(2, 10));
+ }
+ else if (tmp >= powf(2, 11))
+ {
+ do
+ {
+ tmp /= 2.0f;
+ exp++;
+ } while (tmp >= powf(2, 11));
+ }
+
+ exp += 10; /* Normalize the mantissa */
+ exp += 15; /* Exponent is encoded with excess 15 */
+
+ origexp = exp;
+
+ mantissa = (unsigned int) tmp;
+ if ((tmp - mantissa == 0.5f && mantissa % 2 == 1) || /* round half to even */
+ (tmp - mantissa > 0.5f)) mantissa++; /* round to nearest, away from zero */
+ if (mantissa == 2048)
+ {
+ mantissa = 1024;
+ exp++;
+ }
+
+ if (exp > 31)
+ {
+ /* too big */
+ ret = 0x7fff; /* INF */
+ }
+ else if (exp <= 0)
+ {
+ unsigned int rounding = 0;
+
+ exp = origexp;
+
+ /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers */
+ printf("\ttmp = %f\n", tmp);
+ mantissa = (unsigned int) tmp;
+ printf("\tmantissa = %u %s\n", mantissa, int_to_binary(mantissa));
+ mantissa &= 0x3ff;
+ printf("\tmantissa & 0x3ff = %u %s\n", mantissa, int_to_binary(mantissa));
+ mantissa |= 0x400; /* explicit the first bit */
+ printf("\tmantissa | 0x400 = %u %s\n", mantissa, int_to_binary(mantissa));
+ while (exp <= 0)
+ {
+ rounding = mantissa & 1;
+ mantissa >>= 1;
+ exp++;
+ }
+ printf("\trounding = %d\n", rounding);
+ ret = mantissa + rounding;
+ }
+ else
+ {
+ ret = (exp << 10) | (mantissa & 0x3ff);
+ }
+
+ ret |= ((sign ? 1 : 0) << 15); /* Add the sign */
+ return ret;
+}
+
+const char *single_to_binary
+(
+ unsigned int x
+ )
+{
+ static char b[100];
+ int i = 0;
+ b[0] = '\0';
+
+ unsigned int z;
+ for (z = 32768*65536; z > 0; z >>= 1, i++)
+ {
+ strcat(b, ((x & z) == z) ? "1" : "0");
+ if (i == 0 || i == 8) strcat(b, " ");
+ }
+
+ return b;
+}
+
+const char *half_to_binary
+(
+ int x
+ )
+{
+ static char b[100];
+ int i = 0;
+ b[0] = '\0';
+
+ int z;
+ for (z = 32768; z > 0; z >>= 1, i++)
+ {
+ strcat(b, ((x & z) == z) ? "1" : "0");
+ if (i == 0 || i == 5) strcat(b, " ");
+ }
+
+ return b;
+}
+
+static void test_D3DXFloat_Array(void)
+{
+ unsigned int i;
+ void *out = NULL;
+ D3DXFLOAT16 half;
+ FLOAT single;
+ struct
+ {
+ FLOAT single_in;
+
+ /* half_ver2 occurs on WXPPROSP3 (32 bit math), WVISTAADM (32 bit math), W7PRO (32 bit math) */
+ WORD half_ver1, half_ver2;
+
+ /* single_out_ver2 confirms that half -> single conversion is consistent across platforms */
+ FLOAT single_out_ver1, single_out_ver2;
+ } testdata[] = {
+ { 80000.0f, 0x7c00, 0x7ce2, 65536.0f, 80000.0f },
+ { 65503.0f, 0x7bff, 0x7bff, 65504.0f, 65504.0f },
+ { 65504.0f, 0x7bff, 0x7bff, 65504.0f, 65504.0f },
+ { 65520.0f, 0x7bff, 0x7c00, 65504.0f, 65536.0f },
+ { 65521.0f, 0x7c00, 0x7c00, 65536.0f, 65536.0f },
+ { 65534.0f, 0x7c00, 0x7c00, 65536.0f, 65536.0f },
+ { 65535.0f, 0x7c00, 0x7c00, 65535.0f, 65536.0f },
+ { 65536.0f, 0x7c00, 0x7c00, 65536.0f, 65536.0f },
+ { -80000.0f, 0xfc00, 0xfce2, -65536.0f, -80000.0f },
+ { -65503.0f, 0xfbff, 0xfbff, -65504.0f, -65504.0f },
+ { -65504.0f, 0xfbff, 0xfbff, -65504.0f, -65504.0f },
+ { -65520.0f, 0xfbff, 0xfc00, -65504.0f, -65536.0f },
+ { -65521.0f, 0xfc00, 0xfc00, -65536.0f, -65536.0f },
+ { -65534.0f, 0xfc00, 0xfc00, -65536.0f, -65536.0f },
+ { -65535.0f, 0xfc00, 0xfc00, -65535.0f, -65536.0f },
+ { -65536.0f, 0xfc00, 0xfc00, -65536.0f, -65536.0f },
+ { INFINITY, 0x7c00, 0x7fff, 65536.0f, 131008.0f },
+ { -INFINITY, 0xffff, 0xffff, -131008.0f, -131008.0f },
+ { NAN, 0x7fff, 0x7fff, 131008.0f, 131008.0f },
+ { -NAN, 0xffff, 0xffff, -131008.0f, -131008.0f },
+ { 0.0f, 0x0, 0x0, 0.0f, 0.0f },
+ { -0.0f, 0x8000, 0x8000, 0.0f, 0.0f }
+ };
+
+ /* exception on NULL out or in parameter */
+ out = D3DXFloat32To16Array(&half, &single, 0);
+ ok(out == &half, "Got %p, expected %p.\n", out, &half);
+
+ out = D3DXFloat16To32Array(&single, (D3DXFLOAT16 *)&half, 0);
+ ok(out == &single, "Got %p, expected %p.\n", out, &single);
+
+ for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++)
+ {
+ out = D3DXFloat32To16Array(&half, &testdata[i].single_in, 1);
+ ok(out == &half, "Got %p, expected %p.\n", out, &half);
+ ok(half.value == testdata[i].half_ver1 || half.value == testdata[i].half_ver2,
+ "Got %x, expected %x or %x for index %d.\n", half.value, testdata[i].half_ver1,
+ testdata[i].half_ver2, i);
+
+ out = D3DXFloat16To32Array(&single, (D3DXFLOAT16 *)&testdata[i].half_ver1, 1);
+ ok(out == &single, "Got %p, expected %p.\n", out, &single);
+ ok(relative_error(single, testdata[i].single_out_ver1) < admitted_error,
+ "Got %f, expected %f for index %d.\n", single, testdata[i].single_out_ver1, i);
+
+ out = D3DXFloat16To32Array(&single, (D3DXFLOAT16 *)&testdata[i].half_ver2, 1);
+ ok(out == &single, "Got %p, expected %p.\n", out, &single);
+ ok(relative_error(single, testdata[i].single_out_ver2) < admitted_error,
+ "Got %f, expected %f for index %d.\n", single, testdata[i].single_out_ver2, i);
+ }
+
+ {
+ HMODULE dll_handle = NULL;
+ D3DXFLOAT16 res, res2;
+ D3DXFLOAT16* (WINAPI * float32to16)(D3DXFLOAT16 *pout, CONST FLOAT *pin, UINT n);
+ union
+ {
+ float f;
+ DWORD d;
+ } x;
+
+ dll_handle = LoadLibraryA("d3dx9_36_2.dll");
+ if (!dll_handle) skip("init: Could not load d3dx9_36_2.dll.\n");
+
+ float32to16 = (void *)GetProcAddress(dll_handle, "D3DXFloat32To16Array");
+ if (!float32to16)
+ {
+ FreeLibrary(dll_handle);
+ skip("init: Could not get function pointer (D3DXFloat32To16Array).\n");
+ }
+
+ for (i = 0; i < 0xfffff000; i += 0xff)
+ {
+ x.d = i;
+ float32to16(&res, &x.f, 1);
+ D3DXFloat32To16Array(&res2, &x.f, 1);
+ // singles2halfp(&res2, &x.f, 1);
+
+ if (res.value != res2.value)
+ {
+ unsigned int *ptr = (unsigned int *)&x.f;
+ printf("%s: res2 - res = %d\n", single_to_binary(*ptr), res2.value - res.value);
+ float_32_to_16(x.f);
+ // ok(res.value == res2.value, "Failed i=%#x f=%f (%#x!=%#x)\n", i, x.f, res.value, res2.value);
+ /*
+ printf("\t%s: ", single_to_binary(*ptr));
+ printf("%s !=", half_to_binary(res.value));
+ printf(" %s\n", half_to_binary(res2.value));
+ */
+ }
+ //trace("i=%#x f=%f (%#x!=%#x)\n", i, x.f, res.value, res2.value);
+ }
+ FreeLibrary(dll_handle);
+ }
+}
+
START_TEST(math)
{
D3DXColorTest();
@@ -2230,4 +2562,5 @@ START_TEST(math)
test_Matrix_Decompose();
test_Matrix_Transformation2D();
test_D3DXVec_Array();
+ test_D3DXFloat_Array();
}
diff --git a/include/d3dx9math.h b/include/d3dx9math.h
index f842e3e..cdb1deb 100644
--- a/include/d3dx9math.h
+++ b/include/d3dx9math.h
@@ -261,6 +261,21 @@ typedef struct D3DXCOLOR
FLOAT r, g, b, a;
} D3DXCOLOR, *LPD3DXCOLOR;
+typedef struct D3DXFLOAT16
+{
+#ifdef __cplusplus
+ D3DXFLOAT16();
+ D3DXFLOAT16(FLOAT f);
+ D3DXFLOAT16(CONST D3DXFLOAT16 &f);
+
+ operator FLOAT ();
+
+ BOOL operator == (CONST D3DXFLOAT16 &) const;
+ BOOL operator != (CONST D3DXFLOAT16 &) const;
+#endif /* __cplusplus */
+ WORD value;
+} D3DXFLOAT16, *LPD3DXFLOAT16;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -358,6 +373,9 @@ D3DXVECTOR4* WINAPI D3DXVec4Normalize(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv);
D3DXVECTOR4* WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv, CONST D3DXMATRIX *pm);
D3DXVECTOR4* WINAPI D3DXVec4TransformArray(D3DXVECTOR4 *pout, UINT outstride, CONST D3DXVECTOR4 *pv, UINT vstride, CONST D3DXMATRIX *pm, UINT n);
+D3DXFLOAT16 *WINAPI D3DXFloat32To16Array(D3DXFLOAT16 *pout, CONST FLOAT *pin, UINT n);
+FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, CONST D3DXFLOAT16 *pin, UINT n);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/d3dx9math.inl b/include/d3dx9math.inl
index 3cd078a..3f55aef 100644
--- a/include/d3dx9math.inl
+++ b/include/d3dx9math.inl
@@ -851,6 +851,37 @@ inline BOOL D3DXCOLOR::operator != (CONST D3DXCOLOR& col) const
return r != col.r || g != col.g || b != col.b || a != col.a;
}
+inline D3DXFLOAT16::D3DXFLOAT16()
+{
+}
+
+inline D3DXFLOAT16::D3DXFLOAT16(FLOAT f)
+{
+ D3DXFloat32To16Array(this, &f, 1);
+}
+
+inline D3DXFLOAT16::D3DXFLOAT16(CONST D3DXFLOAT16 &f)
+{
+ value = f.value;
+}
+
+inline D3DXFLOAT16::operator FLOAT ()
+{
+ FLOAT f;
+ D3DXFloat16To32Array(&f, this, 1);
+ return f;
+}
+
+inline BOOL D3DXFLOAT16::operator == (CONST D3DXFLOAT16 &f) const
+{
+ return value == f.value;
+}
+
+inline BOOL D3DXFLOAT16::operator != (CONST D3DXFLOAT16 &f) const
+{
+ return value != f.value;
+}
+
#endif /* __cplusplus */
/*_______________D3DXCOLOR_____________________*/
-------------- next part --------------
../../../tools/runtest -q -P wine -M d3dx9_36.dll -T ../../.. -p d3dx9_36_test.exe.so math.c && touch math.ok
0 01100110 00000000000000011001100: res2 - res = 1
tmp = 1024.024902
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000000111001011: res2 - res = 1
tmp = 1024.056030
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000001011001010: res2 - res = 1
tmp = 1024.087158
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000001111001001: res2 - res = 1
tmp = 1024.118286
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000010011001000: res2 - res = 1
tmp = 1024.149414
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000010111000111: res2 - res = 1
tmp = 1024.180542
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000011011000110: res2 - res = 1
tmp = 1024.211670
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01100110 00000000000011111000101: res2 - res = 1
tmp = 1024.242798
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
0 01101000 01000000000000010101011: res2 - res = 1
tmp = 1280.020874
mantissa = 1280 0000010100000000
mantissa & 0x3ff = 256 0000000100000000
mantissa | 0x400 = 1280 0000010100000000
rounding = 1
0 01101000 01000000000000110101010: res2 - res = 1
tmp = 1280.052002
mantissa = 1280 0000010100000000
mantissa & 0x3ff = 256 0000000100000000
mantissa | 0x400 = 1280 0000010100000000
rounding = 1
0 01101001 00100000000000000111011: res2 - res = 1
tmp = 1152.007202
mantissa = 1152 0000010010000000
mantissa & 0x3ff = 128 0000000010000000
mantissa | 0x400 = 1152 0000010010000000
rounding = 1
0 01101001 10100000000000011111010: res2 - res = 1
tmp = 1664.030518
mantissa = 1664 0000011010000000
mantissa & 0x3ff = 640 0000001010000000
mantissa | 0x400 = 1664 0000011010000000
rounding = 1
0 01101010 11010000000000001100010: res2 - res = 1
tmp = 1856.011963
mantissa = 1856 0000011101000000
mantissa & 0x3ff = 832 0000001101000000
mantissa | 0x400 = 1856 0000011101000000
rounding = 1
0 01101011 00101000000000000110110: res2 - res = 1
tmp = 1184.006592
mantissa = 1184 0000010010100000
mantissa & 0x3ff = 160 0000000010100000
mantissa | 0x400 = 1184 0000010010100000
rounding = 1
0 01101011 01001000000000000100110: res2 - res = 1
tmp = 1312.004639
mantissa = 1312 0000010100100000
mantissa & 0x3ff = 288 0000000100100000
mantissa | 0x400 = 1312 0000010100100000
rounding = 1
0 01101011 01101000000000000010110: res2 - res = 1
tmp = 1440.002686
mantissa = 1440 0000010110100000
mantissa & 0x3ff = 416 0000000110100000
mantissa | 0x400 = 1440 0000010110100000
rounding = 1
0 01101011 10001000000000000000110: res2 - res = 1
tmp = 1568.000732
mantissa = 1568 0000011000100000
mantissa & 0x3ff = 544 0000001000100000
mantissa | 0x400 = 1568 0000011000100000
rounding = 1
0 01101101 01111010000000000001100: res2 - res = 1
tmp = 1512.001465
mantissa = 1512 0000010111101000
mantissa & 0x3ff = 488 0000000111101000
mantissa | 0x400 = 1512 0000010111101000
rounding = 1
0 01101101 10000010000000000001000: res2 - res = 1
tmp = 1544.000977
mantissa = 1544 0000011000001000
mantissa & 0x3ff = 520 0000001000001000
mantissa | 0x400 = 1544 0000011000001000
rounding = 1
0 01101101 10001010000000000000100: res2 - res = 1
tmp = 1576.000488
mantissa = 1576 0000011000101000
mantissa & 0x3ff = 552 0000001000101000
mantissa | 0x400 = 1576 0000011000101000
rounding = 1
0 01101101 10010010000000000000000: res2 - res = 1
tmp = 1608.000000
mantissa = 1608 0000011001001000
mantissa & 0x3ff = 584 0000001001001000
mantissa | 0x400 = 1608 0000011001001000
rounding = 1
0 01101110 10000101000000000000110: res2 - res = 1
tmp = 1556.000732
mantissa = 1556 0000011000010100
mantissa & 0x3ff = 532 0000001000010100
mantissa | 0x400 = 1556 0000011000010100
rounding = 1
0 01101110 10001001000000000000100: res2 - res = 1
tmp = 1572.000488
mantissa = 1572 0000011000100100
mantissa & 0x3ff = 548 0000001000100100
mantissa | 0x400 = 1572 0000011000100100
rounding = 1
0 01101110 10001101000000000000010: res2 - res = 1
tmp = 1588.000244
mantissa = 1588 0000011000110100
mantissa & 0x3ff = 564 0000001000110100
mantissa | 0x400 = 1588 0000011000110100
rounding = 1
0 01101110 10010001000000000000000: res2 - res = 1
tmp = 1604.000000
mantissa = 1604 0000011001000100
mantissa & 0x3ff = 580 0000001001000100
mantissa | 0x400 = 1604 0000011001000100
rounding = 1
0 01101111 00001010100000000000011: res2 - res = 1
tmp = 1066.000366
mantissa = 1066 0000010000101010
mantissa & 0x3ff = 42 0000000000101010
mantissa | 0x400 = 1066 0000010000101010
rounding = 1
0 01101111 00001100100000000000010: res2 - res = 1
tmp = 1074.000244
mantissa = 1074 0000010000110010
mantissa & 0x3ff = 50 0000000000110010
mantissa | 0x400 = 1074 0000010000110010
rounding = 1
0 01101111 00001110100000000000001: res2 - res = 1
tmp = 1082.000122
mantissa = 1082 0000010000111010
mantissa & 0x3ff = 58 0000000000111010
mantissa | 0x400 = 1082 0000010000111010
rounding = 1
0 01101111 00010000100000000000000: res2 - res = 1
tmp = 1090.000000
mantissa = 1090 0000010001000010
mantissa & 0x3ff = 66 0000000001000010
mantissa | 0x400 = 1090 0000010001000010
rounding = 1
0 01110000 01001101010000000000001: res2 - res = 1
tmp = 1333.000122
mantissa = 1333 0000010100110101
mantissa & 0x3ff = 309 0000000100110101
mantissa | 0x400 = 1333 0000010100110101
rounding = 1
0 01110000 01001111010000000000000: res2 - res = 1
tmp = 1341.000000
mantissa = 1341 0000010100111101
mantissa & 0x3ff = 317 0000000100111101
mantissa | 0x400 = 1341 0000010100111101
rounding = 1
1 01100110 00000000000000001001100: res2 - res = 1
tmp = 1024.009277
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000000101001011: res2 - res = 1
tmp = 1024.040405
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000001001001010: res2 - res = 1
tmp = 1024.071533
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000001101001001: res2 - res = 1
tmp = 1024.102661
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000010001001000: res2 - res = 1
tmp = 1024.133789
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000010101000111: res2 - res = 1
tmp = 1024.164917
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000011001000110: res2 - res = 1
tmp = 1024.196045
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01100110 00000000000011101000101: res2 - res = 1
tmp = 1024.227173
mantissa = 1024 0000010000000000
mantissa & 0x3ff = 0 0000000000000000
mantissa | 0x400 = 1024 0000010000000000
rounding = 1
1 01101000 01000000000000000101011: res2 - res = 1
tmp = 1280.005249
mantissa = 1280 0000010100000000
mantissa & 0x3ff = 256 0000000100000000
mantissa | 0x400 = 1280 0000010100000000
rounding = 1
1 01101000 01000000000000100101010: res2 - res = 1
tmp = 1280.036377
mantissa = 1280 0000010100000000
mantissa & 0x3ff = 256 0000000100000000
mantissa | 0x400 = 1280 0000010100000000
rounding = 1
1 01101001 00100000000000010111010: res2 - res = 1
tmp = 1152.022705
mantissa = 1152 0000010010000000
mantissa & 0x3ff = 128 0000000010000000
mantissa | 0x400 = 1152 0000010010000000
rounding = 1
1 01101001 10100000000000001111010: res2 - res = 1
tmp = 1664.014893
mantissa = 1664 0000011010000000
mantissa & 0x3ff = 640 0000001010000000
mantissa | 0x400 = 1664 0000011010000000
rounding = 1
1 01101010 00010000000000001000010: res2 - res = 1
tmp = 1088.008057
mantissa = 1088 0000010001000000
mantissa & 0x3ff = 64 0000000001000000
mantissa | 0x400 = 1088 0000010001000000
rounding = 1
1 01101010 01010000000000000100010: res2 - res = 1
tmp = 1344.004150
mantissa = 1344 0000010101000000
mantissa & 0x3ff = 320 0000000101000000
mantissa | 0x400 = 1344 0000010101000000
rounding = 1
1 01101010 10010000000000000000010: res2 - res = 1
tmp = 1600.000244
mantissa = 1600 0000011001000000
mantissa & 0x3ff = 576 0000001001000000
mantissa | 0x400 = 1600 0000011001000000
rounding = 1
1 01101100 01010100000000000011111: res2 - res = 1
tmp = 1360.003784
mantissa = 1360 0000010101010000
mantissa & 0x3ff = 336 0000000101010000
mantissa | 0x400 = 1360 0000010101010000
rounding = 1
1 01101100 01100100000000000010111: res2 - res = 1
tmp = 1424.002808
mantissa = 1424 0000010110010000
mantissa & 0x3ff = 400 0000000110010000
mantissa | 0x400 = 1424 0000010110010000
rounding = 1
1 01101100 01110100000000000001111: res2 - res = 1
tmp = 1488.001831
mantissa = 1488 0000010111010000
mantissa & 0x3ff = 464 0000000111010000
mantissa | 0x400 = 1488 0000010111010000
rounding = 1
1 01101100 10000100000000000000111: res2 - res = 1
tmp = 1552.000854
mantissa = 1552 0000011000010000
mantissa & 0x3ff = 528 0000001000010000
mantissa | 0x400 = 1552 0000011000010000
rounding = 1
1 01110000 01001100010000000000001: res2 - res = 1
tmp = 1329.000122
mantissa = 1329 0000010100110001
mantissa & 0x3ff = 305 0000000100110001
mantissa | 0x400 = 1329 0000010100110001
rounding = 1
1 01110000 01001110010000000000000: res2 - res = 1
tmp = 1337.000000
mantissa = 1337 0000010100111001
mantissa & 0x3ff = 313 0000000100111001
mantissa | 0x400 = 1337 0000010100111001
rounding = 1
More information about the wine-devel
mailing list