You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

156 regels
4.5 KiB

  1. //
  2. // Lol Engine - Sample math program: chek trigonometric functions
  3. //
  4. // Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdio>
  14. #if USE_SDL && defined __APPLE__
  15. # include <SDL_main.h>
  16. #endif
  17. #include "core.h"
  18. using namespace lol;
  19. using namespace std;
  20. float adjustf(float f, int i) __attribute__((noinline));
  21. float adjustf(float f, int i)
  22. {
  23. union { float f; uint32_t x; } u = { f };
  24. u.x += i;
  25. return u.f;
  26. }
  27. double adjust(double f, int i) __attribute__((noinline));
  28. double adjust(double f, int i)
  29. {
  30. union { double f; uint64_t x; } u = { f };
  31. u.x += i;
  32. return u.f;
  33. }
  34. static void inspect(float f)
  35. {
  36. union { float f; uint32_t x; } u = { f };
  37. printf("%08x %14.12g -- ", u.x, u.f);
  38. int i = (u.x & 0x7fffffu) | 0x800000u;
  39. int j = 23 - ((u.x >> 23) & 0xff) + ((1 << 7) - 1);
  40. if (u.f <= 0)
  41. i = -i;
  42. printf("%i / 2^%i = %14.12g\n", i, j, (float)i / (1LLu << j));
  43. }
  44. //#define float double
  45. #if 1
  46. static float const a0 = 1.0;
  47. static float const a1 = -0.1666666666663036;
  48. static float const a2 = 0.008333333325075758;
  49. static float const a3 = -0.0001984126372689299;
  50. static float const a4 = 2.755533925906394e-06;
  51. static float const a5 = -2.476042626296988e-08;
  52. static float const a6 = 0.0;
  53. #elif 0
  54. static float const a0 = adjust(0.9999999999999376, 0);
  55. static float const a1 = adjust(-0.1666666666643236, 0);
  56. static float const a2 = adjust(0.008333333318766562, 0);
  57. static float const a3 = adjust(-0.0001984126641174625, 0);
  58. static float const a4 = adjust(2.755693193297308e-006, 0);
  59. static float const a5 = adjust(-2.502951900290311e-008, 0);
  60. static float const a6 = adjust(1.540117123154927e-010, 0);
  61. #elif 0
  62. static float const a0 = adjust(1.0, 0);
  63. static float const a1 = adjust(-0.1666666666372165, 0);
  64. static float const a2 = adjust(0.008333332748323419, 0);
  65. static float const a3 = adjust(-0.0001984108245332497, 0);
  66. static float const a4 = adjust(2.753619853326498e-06, 0);
  67. static float const a5 = adjust(-2.407483949485896e-08, 0);
  68. static float const a6 = 0.0;
  69. #else
  70. static float const a0 = adjust(0.9999999946887117, 0);
  71. static float const a1 = adjust(-0.1666665668590824, 0);
  72. static float const a2 = adjust(0.008333025160523476, 0);
  73. static float const a3 = adjust(-0.0001980741944205014, 0);
  74. static float const a4 = adjust(2.60190356966559e-06, 0); // -900 in floats
  75. static float const a5 = 0.0;
  76. static float const a6 = 0.0;
  77. #endif
  78. static float floatsin(float f)
  79. {
  80. return lol_sin(f);
  81. //static float const k = (float)real::R_2_PI;
  82. //f *= k;
  83. float f2 = f * f;
  84. float f4 = f2 * f2;
  85. return f * (a0 + f4 * (a2 + f4 * (a4 + f4 * a6)) + f2 * (a1 + f4 * (a3 + f4 * a5)));
  86. //return f * (a0 + f2 * (a1 + f2 * (a2 + f2 * (a3 + f2 * (a4 + f2 * (a5 + f2 * a6))))));
  87. //return f * (a0 + a1 * f2 + a2 * f2 * f2 + a3 * f2 * f2 * f2 + a4 * f2 * f2 * f2 * f2 + a5 * f2 * f2 * f2 * f2 * f2 + a6 * f2 * f2 * f2 * f2 * f2 * f2);
  88. #undef float
  89. }
  90. int main(int argc, char **argv)
  91. {
  92. typedef union { float f; uint32_t x; } flint;
  93. int error[5] = { 0 };
  94. inspect(a0);
  95. inspect(a1);
  96. inspect(a2);
  97. inspect(a3);
  98. inspect(a4);
  99. inspect(a5);
  100. //flint v = { 1.433971524239 };
  101. flint v = { 1.555388212204 };
  102. inspect(v.f);
  103. printf("sinf: ");
  104. flint w = { sinf(adjustf(v.f, 0)) };
  105. inspect(w.f);
  106. printf("lols: ");
  107. flint z = { lol_sin(adjustf(v.f, 0)) };
  108. inspect(z.f);
  109. printf("-- START --\n");
  110. for (flint u = { (float)real::R_PI_2 }; u.f > 1e-30; u.x -= 1)
  111. {
  112. union { float f; uint32_t x; } s1 = { sinf(adjustf(u.f, 0)) };
  113. union { float f; uint32_t x; } s2 = { floatsin(adjustf(u.f, 0)) };
  114. int e = abs((int)(s1.x - s2.x));
  115. switch (e)
  116. {
  117. case 3:
  118. case 2:
  119. case 1:
  120. inspect(u.f);
  121. printf("sinf: ");
  122. inspect(sinf(u.f));
  123. if (fabs((double)s1.f - (double)s2.f) > 1e-10 * fabs(s1.f))
  124. printf("%15.13g %08x: %15.13g %15.13g %08x %08x\n", u.f, u.x, s1.f, s2.f, s1.x, s2.x);
  125. case 0:
  126. error[e]++;
  127. break;
  128. default:
  129. error[4]++;
  130. break;
  131. }
  132. }
  133. printf("exact: %i off by 1: %i by 2: %i by 3: %i error: %i\n",
  134. error[0], error[1], error[2], error[3], error[4]);
  135. return EXIT_SUCCESS;
  136. }