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.

пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #include "core.h"
  15. using namespace lol;
  16. using namespace std;
  17. float adjustf(float f, int i) __attribute__((noinline));
  18. float adjustf(float f, int i)
  19. {
  20. union { float f; uint32_t x; } u = { f };
  21. u.x += i;
  22. return u.f;
  23. }
  24. double adjust(double f, int i) __attribute__((noinline));
  25. double adjust(double f, int i)
  26. {
  27. union { double f; uint64_t x; } u = { f };
  28. u.x += i;
  29. return u.f;
  30. }
  31. static void inspect(float f)
  32. {
  33. union { float f; uint32_t x; } u = { f };
  34. printf("%08x %14.12g -- ", u.x, u.f);
  35. int i = (u.x & 0x7fffffu) | 0x800000u;
  36. int j = 23 - ((u.x >> 23) & 0xff) + ((1 << 7) - 1);
  37. if (u.f <= 0)
  38. i = -i;
  39. printf("%i / 2^%i = %14.12g\n", i, j, (float)i / (1LLu << j));
  40. }
  41. //#define float double
  42. #if 1
  43. static float const a0 = 1.0;
  44. static float const a1 = -0.1666666666663036;
  45. static float const a2 = 0.008333333325075758;
  46. static float const a3 = -0.0001984126372689299;
  47. static float const a4 = 2.755533925906394e-06;
  48. static float const a5 = -2.476042626296988e-08;
  49. static float const a6 = 0.0;
  50. #elif 0
  51. static float const a0 = adjust(0.9999999999999376, 0);
  52. static float const a1 = adjust(-0.1666666666643236, 0);
  53. static float const a2 = adjust(0.008333333318766562, 0);
  54. static float const a3 = adjust(-0.0001984126641174625, 0);
  55. static float const a4 = adjust(2.755693193297308e-006, 0);
  56. static float const a5 = adjust(-2.502951900290311e-008, 0);
  57. static float const a6 = adjust(1.540117123154927e-010, 0);
  58. #elif 0
  59. static float const a0 = adjust(1.0, 0);
  60. static float const a1 = adjust(-0.1666666666372165, 0);
  61. static float const a2 = adjust(0.008333332748323419, 0);
  62. static float const a3 = adjust(-0.0001984108245332497, 0);
  63. static float const a4 = adjust(2.753619853326498e-06, 0);
  64. static float const a5 = adjust(-2.407483949485896e-08, 0);
  65. static float const a6 = 0.0;
  66. #else
  67. static float const a0 = adjust(0.9999999946887117, 0);
  68. static float const a1 = adjust(-0.1666665668590824, 0);
  69. static float const a2 = adjust(0.008333025160523476, 0);
  70. static float const a3 = adjust(-0.0001980741944205014, 0);
  71. static float const a4 = adjust(2.60190356966559e-06, 0); // -900 in floats
  72. static float const a5 = 0.0;
  73. static float const a6 = 0.0;
  74. #endif
  75. static float floatsin(float f)
  76. {
  77. return lol_sin(f);
  78. //static float const k = (float)real::R_2_PI;
  79. //f *= k;
  80. float f2 = f * f;
  81. float f4 = f2 * f2;
  82. return f * (a0 + f4 * (a2 + f4 * (a4 + f4 * a6)) + f2 * (a1 + f4 * (a3 + f4 * a5)));
  83. //return f * (a0 + f2 * (a1 + f2 * (a2 + f2 * (a3 + f2 * (a4 + f2 * (a5 + f2 * a6))))));
  84. //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);
  85. #undef float
  86. }
  87. int main(void)
  88. {
  89. typedef union { float f; uint32_t x; } flint;
  90. int error[5] = { 0 };
  91. inspect(a0);
  92. inspect(a1);
  93. inspect(a2);
  94. inspect(a3);
  95. inspect(a4);
  96. inspect(a5);
  97. //flint v = { 1.433971524239 };
  98. flint v = { 1.555388212204 };
  99. inspect(v.f);
  100. printf("sinf: ");
  101. flint w = { sinf(adjustf(v.f, 0)) };
  102. inspect(w.f);
  103. printf("lols: ");
  104. flint z = { lol_sin(adjustf(v.f, 0)) };
  105. inspect(z.f);
  106. printf("-- START --\n");
  107. for (flint u = { (float)real::R_PI_2 }; u.f > 1e-30; u.x -= 1)
  108. {
  109. union { float f; uint32_t x; } s1 = { sinf(adjustf(u.f, 0)) };
  110. union { float f; uint32_t x; } s2 = { floatsin(adjustf(u.f, 0)) };
  111. int e = abs((int)(s1.x - s2.x));
  112. switch (e)
  113. {
  114. case 3:
  115. case 2:
  116. case 1:
  117. inspect(u.f);
  118. printf("sinf: ");
  119. inspect(sinf(u.f));
  120. if (fabs((double)s1.f - (double)s2.f) > 1e-10 * fabs(s1.f))
  121. printf("%15.13g %08x: %15.13g %15.13g %08x %08x\n", u.f, u.x, s1.f, s2.f, s1.x, s2.x);
  122. case 0:
  123. error[e]++;
  124. break;
  125. default:
  126. error[4]++;
  127. break;
  128. }
  129. }
  130. printf("exact: %i off by 1: %i by 2: %i by 3: %i error: %i\n",
  131. error[0], error[1], error[2], error[3], error[4]);
  132. return EXIT_SUCCESS;
  133. }