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.
 
 
 

100 lines
2.6 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. #include "core.h"
  15. using namespace lol;
  16. using namespace std;
  17. static float adjust(float f, int i)
  18. {
  19. union { float f; uint32_t x; } u = { f };
  20. u.x += i;
  21. return u.f;
  22. }
  23. static void inspect(float f)
  24. {
  25. union { float f; uint32_t x; } u = { f };
  26. printf("%08x %g -- ", u.x, u.f);
  27. int i = (u.x & 0x7fffffu) | 0x800000u;
  28. int j = 23 - ((u.x >> 23) & 0xff) + ((1 << 7) - 1);
  29. if (u.f <= 0)
  30. i = -i;
  31. printf("%i / 2^%i = %g\n", i, j, (float)i / (1LLu << j));
  32. }
  33. static float const a0 = adjust(1.0, 0);
  34. static float const a1 = adjust(-0.1666666666372165, 0);
  35. static float const a2 = adjust(0.008333332748323419, 0);
  36. static float const a3 = adjust(-0.0001984108245332497, 0);
  37. static float const a4 = adjust(2.753619853326498e-06, 0);
  38. static float const a5 = adjust(-2.407483949485896e-08, 0);
  39. static float floatsin(float f)
  40. {
  41. //return lol_sin(f);
  42. //#define float double
  43. //static float const k = (float)real::R_2_PI;
  44. //f *= k;
  45. float f2 = f * f;
  46. float f4 = f2 * f2;
  47. //return f * (a0 + f4 * (a2 + f4 * a4) + f2 * (a1 + f4 * (a3 + f4 * a5)));
  48. //return f * (a0 + f2 * (a1 + f2 * (a2 + f2 * (a3 + f2 * (a4 + f2 * a5)))));
  49. return f * (a0 + a1 * f2 + a2 * f2 * f2 + a3 * f2 * f2 * f2 + a4 * f2 * f2 * f2 * f2 + a5 * f2 * f2 * f2 * f2 * f2);
  50. #undef float
  51. }
  52. int main(void)
  53. {
  54. int error[5] = { 0 };
  55. inspect(a0);
  56. inspect(a1);
  57. inspect(a2);
  58. inspect(a3);
  59. inspect(a4);
  60. inspect(a5);
  61. for (float f = (float)real::R_PI_2; f > 1e-30; f = adjust(f, -1))
  62. {
  63. union { float f; uint32_t x; } s1 = { sinf(f) };
  64. union { float f; uint32_t x; } s2 = { floatsin(f) };
  65. int e = abs((int)(s1.x - s2.x));
  66. switch (e)
  67. {
  68. case 0:
  69. case 1:
  70. case 2:
  71. case 3:
  72. error[e]++;
  73. break;
  74. default:
  75. if (fabs((double)s1.f - (double)s2.f) > 1e-10 * fabs(s1.f))
  76. printf("%16.14g: %16.14g %16.14g %08x %08x\n", f, s1.f, s2.f, s1.x, s2.x);
  77. error[4]++;
  78. break;
  79. }
  80. }
  81. printf("exact: %i off by 1: %i by 2: %i by 3: %i error: %i\n",
  82. error[0], error[1], error[2], error[3], error[4]);
  83. return EXIT_SUCCESS;
  84. }