test-femode.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* Test femode_t functions.
  2. Copyright (C) 2016-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <fenv.h>
  16. #include <stdio.h>
  17. #include <math-tests.h>
  18. static int
  19. test_mmee (int mode1, int mode2, int exc1, int exc2)
  20. {
  21. int result = 0;
  22. printf ("testing %x %x %x %x\n", (unsigned int) mode1, (unsigned int) mode2,
  23. (unsigned int) exc1, (unsigned int) exc2);
  24. feclearexcept (FE_ALL_EXCEPT);
  25. int ret = fesetround (mode1);
  26. if (ret != 0)
  27. {
  28. if (ROUNDING_TESTS (float, mode1))
  29. {
  30. puts ("first fesetround failed unexpectedly");
  31. result = 1;
  32. }
  33. else
  34. puts ("first fesetround failed, cannot test");
  35. return result;
  36. }
  37. ret = fesetexcept (exc1);
  38. if (ret != 0)
  39. {
  40. if (EXCEPTION_TESTS (float) || exc1 == 0)
  41. {
  42. puts ("first fesetexcept failed unexpectedly");
  43. result = 1;
  44. }
  45. else
  46. puts ("first fesetexcept failed, cannot test");
  47. return result;
  48. }
  49. femode_t saved;
  50. ret = fegetmode (&saved);
  51. if (ret != 0)
  52. {
  53. puts ("fegetmode failed");
  54. result = 1;
  55. return result;
  56. }
  57. feclearexcept (FE_ALL_EXCEPT);
  58. ret = fesetround (mode2);
  59. if (ret != 0)
  60. {
  61. if (ROUNDING_TESTS (float, mode2))
  62. {
  63. puts ("second fesetround failed unexpectedly");
  64. result = 1;
  65. }
  66. else
  67. puts ("second fesetround failed, cannot test");
  68. return result;
  69. }
  70. ret = fesetexcept (exc2);
  71. if (ret != 0)
  72. {
  73. if (EXCEPTION_TESTS (float) || exc2 == 0)
  74. {
  75. puts ("second fesetexcept failed unexpectedly");
  76. result = 1;
  77. }
  78. else
  79. puts ("second fesetexcept failed, cannot test");
  80. return result;
  81. }
  82. ret = fesetmode (&saved);
  83. if (ret != 0)
  84. {
  85. puts ("fesetmode failed");
  86. result = 1;
  87. return result;
  88. }
  89. /* Verify that the rounding mode was restored but the exception
  90. flags remain unchanged. */
  91. ret = fegetround ();
  92. if (ret != mode1)
  93. {
  94. printf ("restored rounding mode %x not %x\n", (unsigned int) ret,
  95. (unsigned int) mode1);
  96. result = 1;
  97. }
  98. ret = fetestexcept (FE_ALL_EXCEPT);
  99. if (ret != exc2)
  100. {
  101. printf ("exceptions %x not %x\n", (unsigned int) ret,
  102. (unsigned int) exc2);
  103. result = 1;
  104. }
  105. /* Likewise, with default modes. */
  106. ret = fesetmode (FE_DFL_MODE);
  107. if (ret != 0)
  108. {
  109. puts ("fesetmode (FE_DFL_MODE) failed");
  110. result = 1;
  111. return result;
  112. }
  113. ret = fegetround ();
  114. if (ret != FE_TONEAREST)
  115. {
  116. printf ("FE_DFL_MODE rounding mode %x not %x\n", (unsigned int) ret,
  117. (unsigned int) FE_TONEAREST);
  118. result = 1;
  119. }
  120. ret = fetestexcept (FE_ALL_EXCEPT);
  121. if (ret != exc2)
  122. {
  123. printf ("FE_DFL_MODE exceptions %x not %x\n", (unsigned int) ret,
  124. (unsigned int) exc2);
  125. result = 1;
  126. }
  127. return result;
  128. }
  129. static int
  130. test_mme (int mode1, int mode2, int exc1)
  131. {
  132. int result = 0;
  133. result |= test_mmee (mode1, mode2, exc1, 0);
  134. result |= test_mmee (mode1, mode2, exc1, FE_ALL_EXCEPT);
  135. #ifdef FE_DIVBYZERO
  136. result |= test_mmee (mode1, mode2, exc1, FE_DIVBYZERO);
  137. #endif
  138. #ifdef FE_INEXACT
  139. result |= test_mmee (mode1, mode2, exc1, FE_INEXACT);
  140. #endif
  141. #ifdef FE_INVALID
  142. result |= test_mmee (mode1, mode2, exc1, FE_INVALID);
  143. #endif
  144. #ifdef FE_OVERFLOW
  145. result |= test_mmee (mode1, mode2, exc1, FE_OVERFLOW);
  146. #endif
  147. #ifdef FE_UNDERFLOW
  148. result |= test_mmee (mode1, mode2, exc1, FE_UNDERFLOW);
  149. #endif
  150. return result;
  151. }
  152. static int
  153. test_mm (int mode1, int mode2)
  154. {
  155. int result = 0;
  156. result |= test_mme (mode1, mode2, 0);
  157. result |= test_mme (mode1, mode2, FE_ALL_EXCEPT);
  158. #ifdef FE_DIVBYZERO
  159. result |= test_mme (mode1, mode2, FE_DIVBYZERO);
  160. #endif
  161. #ifdef FE_INEXACT
  162. result |= test_mme (mode1, mode2, FE_INEXACT);
  163. #endif
  164. #ifdef FE_INVALID
  165. result |= test_mme (mode1, mode2, FE_INVALID);
  166. #endif
  167. #ifdef FE_OVERFLOW
  168. result |= test_mme (mode1, mode2, FE_OVERFLOW);
  169. #endif
  170. #ifdef FE_UNDERFLOW
  171. result |= test_mme (mode1, mode2, FE_UNDERFLOW);
  172. #endif
  173. return result;
  174. }
  175. static int
  176. test_m (int mode1)
  177. {
  178. int result = 0;
  179. #ifdef FE_DOWNWARD
  180. result |= test_mm (mode1, FE_DOWNWARD);
  181. #endif
  182. #ifdef FE_TONEAREST
  183. result |= test_mm (mode1, FE_TONEAREST);
  184. #endif
  185. #ifdef FE_TOWARDZERO
  186. result |= test_mm (mode1, FE_TOWARDZERO);
  187. #endif
  188. #ifdef FE_UPWARD
  189. result |= test_mm (mode1, FE_UPWARD);
  190. #endif
  191. return result;
  192. }
  193. static int
  194. do_test (void)
  195. {
  196. int result = 0;
  197. #ifdef FE_DOWNWARD
  198. result |= test_m (FE_DOWNWARD);
  199. #endif
  200. #ifdef FE_TONEAREST
  201. result |= test_m (FE_TONEAREST);
  202. #endif
  203. #ifdef FE_TOWARDZERO
  204. result |= test_m (FE_TOWARDZERO);
  205. #endif
  206. #ifdef FE_UPWARD
  207. result |= test_m (FE_UPWARD);
  208. #endif
  209. return result;
  210. }
  211. #define TEST_FUNCTION do_test ()
  212. #include "../test-skeleton.c"