Test questions: defining test structures as global variables and quick floating point reference
Dear All: Thank you again for all your help. To remind you, I am working on fixing: http://bugs.winehq.org/show_bug.cgi?id=22918 And, as we are currently in code freeze, I have a GitHub repo here in which I am making relevant changes: http://github.com/misha680/wine/commits/master I am going over my patches and had a few questions with which I'd appreciate your help. Specifically, I'd like to know the answers, if possible, sooner rather than later, so that in case things come up later when I submit patches, I can simply reference the relevant wine-devel discussions. My questions are as follows. 1) In some tests, I need to declare global variables to store test data. For example, in this patch: http://github.com/misha680/wine/commit/17d2bb17d5868bd533dba6f1e1f9d8e6753b3... I declare these structures: #define MAX_CYLINDER_VERTICES 1000 /* arbitrary */ D3DXVECTOR3 cylinder_test_vertex_data[MAX_CYLINDER_VERTICES]; 1a) Is this kosher? The other option would be to dynamically allocate, but this seems like a lot of overhead for a test. If I declare such structures _within_ functions, I seem to have problems with memory access to these structures (perhaps they are too big for stack)? 1b) I utilize similar structures in other tests. Currently, I declare a separate structure for each test? Is it preferable to: i) _declare a separate structure for each test, say: #define MAX_CYLINDER_VERTICES 1000 /* arbitrary */ D3DXVECTOR3 cylinder_test_vertex_data[MAX_CYLINDER_VERTICES]; #define MAX_SPHERE_VERTICES 1000 /* arbitrary */ D3DXVECTOR3 sphere_test_vertex_data[MAX_CYLINDER_VERTICES]; or ii) _declare a common structure for _all_ tests #define MAX_ALL_TEST_VERTICES 1000 /* arbitrary */ D3DXVECTOR3 all_test_vertex_data[MAX_CYLINDER_VERTICES]; and use such a structure in all my tests? 2) Finally, as you have noticed, per Dan's advice, I have implemented this function: /* http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm * "I think the answer is 10,000 but since floating point math is imperfect I’ll accept the maxUlps floats above and the maxUlps floats below that value." */ static BOOLEAN AlmostEqual2sComplement(float A, float B, int maxUlps) { int aInt, bInt, intDiff; /* Make sure maxUlps is non-negative and small enough that the * default NAN won't compare as equal to anything. */ assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); aInt= *(int*)&A; /* Make aInt lexicographically ordered as a twos-complement int */ if (aInt < 0) aInt = 0x80000000 - aInt; /* Make bInt lexicographically ordered as a twos-complement int */ bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; intDiff = abs(aInt - bInt); if (intDiff <= maxUlps) return TRUE; return FALSE; } It works very nicely, and is most accurate. However, I have since noticed that mesh.c has the following functions defined: #define admitted_error 0.0001f #define compare_vertex_sizes(type, exp) \ got=D3DXGetFVFVertexSize(type); \ ok(got==exp, "Expected: %d, Got: %d\n", exp, got); static BOOL compare(FLOAT u, FLOAT v) { return (fabs(u-v) < admitted_error); } static BOOL compare_vec3(D3DXVECTOR3 u, D3DXVECTOR3 v) { return ( compare(u.x, v.x) && compare(u.y, v.y) && compare(u.z, v.z) ); } These seem, if anything, much simpler, and, I have noticed in the case of very complicated test data, more accurate. I am going to change my code to use these latter functions, even though they are not technically as good comparators as my current ones. If there are any objections/comments re this, please let me know. Thank you Misha
participants (1)
-
Misha Koshelev