Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.21 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <x86intrin.h>
  5. #include <math.h>
  6.  
  7. #define ERROR_MAX 100
  8.  
  9. // dumb funcs to test...won't agree at -0 but don't care
  10. float func0(float x) { return x>=0 ? 1.f : -1.f; }
  11. float func1(float x) { return copysign(1.f,x); }
  12.  
  13. //-------------------------------
  14.  
  15. #if !defined(_MSC_VER)
  16. #define FP32_MIN 0x1.0p-126f // smallest normal
  17. #define FP32_MIN_DN 0x1.0p-149f // smallest denormal
  18. #else
  19. #include <float.h>
  20. #define FP32_MIN FLT_MIN
  21. #define FP32_MIN_DN FLT_TRUE_MIN
  22. #endif
  23.  
  24. uint32_t ecount;
  25.  
  26. float error_table[ERROR_MAX];
  27.  
  28. void reset_test()
  29. {
  30. ecount = 0;
  31. }
  32.  
  33. void test_via_integer()
  34. {
  35. union { float f; uint32_t i; } cnt;
  36. cnt.f = 0;
  37.  
  38. do {
  39. float f0 = func0(cnt.f);
  40. float f1 = func1(cnt.f);
  41. cnt.i++;
  42.  
  43. if (f0 == f1) continue;
  44.  
  45. error_table[ecount++] = cnt.f;
  46. if (ecount == ERROR_MAX) return;
  47.  
  48. } while(cnt.i != 0x7f800000);
  49. }
  50.  
  51. void test_via_ulp()
  52. {
  53. float x = 0;
  54. float ulp = FP32_MIN_DN;
  55. float e = 2.f*FP32_MIN;
  56. float ddf;
  57.  
  58. do {
  59. while(x != e) {
  60. float f0 = func0(x);
  61. float f1 = func1(x);
  62.  
  63. x += ulp;
  64.  
  65. if (f0 == f1) continue;
  66.  
  67. error_table[ecount++] = x;
  68. if (ecount == ERROR_MAX) return;
  69. }
  70.  
  71. ulp += ulp;
  72. e += e;
  73.  
  74. } while(x <= 0x1.0p127f);
  75. }
  76.  
  77.  
  78. void run_tests()
  79. {
  80. uint64_t s0,s1;
  81.  
  82. printf("integer walk\n");
  83. for(uint32_t t=0; t<10; t++) {
  84. s0 = _rdtsc();
  85. test_via_integer();
  86. s1 = _rdtsc();
  87. printf("%f\n",1.0*(s1-s0));
  88. }
  89.  
  90. printf("ulp walk\n");
  91. for(uint32_t t=0; t<10; t++) {
  92. s0 = _rdtsc();
  93. test_via_ulp();
  94. s1 = _rdtsc();
  95. printf("%f\n",1.0*(s1-s0));
  96. }
  97. }
  98.  
  99.  
  100. // walk through all the positive ordered binary32, both by integer & ulp increment
  101. void sanity_check()
  102. {
  103. uint32_t i=0;
  104. union { float f; uint32_t i; } cnt;
  105. cnt.f = 0;
  106.  
  107. float x = 0;
  108. float ulp = FP32_MIN_DN;
  109. float e = 2.f*FP32_MIN;
  110. float ddf;
  111.  
  112. do {
  113. while(x != e) {
  114. i++;
  115. cnt.i++;
  116. x += ulp;
  117.  
  118. if (x == cnt.f) continue;
  119.  
  120. printf("broken --- %08x %a %a | %a\n", i, cnt.f, x,ulp);
  121. return;
  122. }
  123.  
  124. ulp += ulp;
  125. e += e;
  126.  
  127. } while(x <= 0x1.0p127f);
  128. }
  129.  
  130.  
  131. void main(int argc, char** argv)
  132. {
  133. //sanity_check();
  134. run_tests();
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement