fix16_exp_unittests.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <fix16.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <stdbool.h>
  5. #include "unittests.h"
  6. #define delta(a,b) (((a)>=(b)) ? (a)-(b) : (b)-(a))
  7. int main()
  8. {
  9. int status = 0;
  10. {
  11. COMMENT("Testing fix16_exp() corner cases");
  12. TEST(fix16_exp(0) == fix16_one);
  13. TEST(fix16_exp(fix16_minimum) == 0);
  14. TEST(fix16_exp(fix16_maximum) == fix16_maximum);
  15. }
  16. {
  17. COMMENT("Testing fix16_exp() accuracy over -11..4");
  18. fix16_t max_delta = -1;
  19. fix16_t worst = 0;
  20. fix16_t sum = 0;
  21. int count = 0;
  22. fix16_t a;
  23. for (a = fix16_from_dbl(-11.0); a < fix16_from_dbl(4.0); a += 31)
  24. {
  25. fix16_t result = fix16_exp(a);
  26. fix16_t resultf = fix16_from_dbl(exp(fix16_to_dbl(a)));
  27. fix16_t d = delta(result, resultf);
  28. if (d > max_delta)
  29. {
  30. max_delta = d;
  31. worst = a;
  32. }
  33. sum += d;
  34. count++;
  35. }
  36. printf("Worst delta %d with input %d\n", max_delta, worst);
  37. printf("Average delta %0.2f\n", (float)sum / count);
  38. TEST(max_delta < 200);
  39. }
  40. {
  41. COMMENT("Testing fix16_exp() accuracy over full range");
  42. float max_delta = -1;
  43. fix16_t worst = 0;
  44. float sum = 0;
  45. int count = 0;
  46. fix16_t a;
  47. // Test the whole range of results 0..32768 with a bit less samples
  48. for (a = -772243; a < 681391; a += 113)
  49. {
  50. fix16_t result = fix16_exp(a);
  51. fix16_t resultf = fix16_from_dbl(exp(fix16_to_dbl(a)));
  52. fix16_t d1 = delta(result, resultf);
  53. if (d1 > 0) d1--; // Forgive +-1 for the fix16_t inaccuracy
  54. float d = (float)d1 / resultf * 100;
  55. if (resultf < 1000) continue; // Percentages can explode when result is almost 0.
  56. if (d > max_delta)
  57. {
  58. max_delta = d;
  59. worst = a;
  60. }
  61. sum += d;
  62. count++;
  63. }
  64. printf("Worst delta %0.4f%% with input %d\n", max_delta, worst);
  65. printf("Average delta %0.4f%%\n", sum / count);
  66. TEST(max_delta < 1);
  67. }
  68. {
  69. COMMENT("Testing fix16_log() accuracy over full range");
  70. fix16_t max_delta = -1;
  71. fix16_t worst = 0;
  72. fix16_t sum = 0;
  73. int count = 0;
  74. fix16_t a;
  75. for (a = 100; a > 0 && a < fix16_maximum - 7561; a += 7561)
  76. {
  77. fix16_t result = fix16_log(a);
  78. fix16_t resultf = fix16_from_dbl(log(fix16_to_dbl(a)));
  79. fix16_t d = delta(result, resultf);
  80. if (d > max_delta)
  81. {
  82. max_delta = d;
  83. worst = a;
  84. }
  85. sum += d;
  86. count++;
  87. }
  88. printf("Worst delta %d with input %d\n", max_delta, worst);
  89. printf("Average delta %0.2f\n", (float)sum / count);
  90. TEST(max_delta < 20);
  91. }
  92. if (status != 0)
  93. fprintf(stdout, "\n\nSome tests FAILED!\n");
  94. return status;
  95. }