Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. }