round.m4 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # round.m4 serial 16
  2. dnl Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
  3. dnl This file is free software; the Free Software Foundation
  4. dnl gives unlimited permission to copy and/or distribute it,
  5. dnl with or without modifications, as long as this notice is preserved.
  6. AC_DEFUN([gl_FUNC_ROUND],
  7. [
  8. m4_divert_text([DEFAULTS], [gl_round_required=plain])
  9. AC_REQUIRE([gl_MATH_H_DEFAULTS])
  10. dnl Persuade glibc <math.h> to declare round().
  11. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
  12. gl_CHECK_MATH_LIB([ROUND_LIBM], [x = round (x);],
  13. [extern
  14. #ifdef __cplusplus
  15. "C"
  16. #endif
  17. double round (double);
  18. ])
  19. if test "$ROUND_LIBM" != missing; then
  20. HAVE_ROUND=1
  21. dnl Also check whether it's declared.
  22. dnl IRIX 6.5 has round() in libm but doesn't declare it in <math.h>.
  23. AC_CHECK_DECLS([round], , [HAVE_DECL_ROUND=0], [[#include <math.h>]])
  24. dnl Test whether round() produces correct results. On NetBSD 3.0, for
  25. dnl x = 1/2 - 2^-54, the system's round() returns a wrong result.
  26. AC_REQUIRE([AC_PROG_CC])
  27. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  28. AC_CACHE_CHECK([whether round works], [gl_cv_func_round_works],
  29. [
  30. save_LIBS="$LIBS"
  31. LIBS="$LIBS $ROUND_LIBM"
  32. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  33. #include <float.h>
  34. #include <math.h>
  35. extern
  36. #ifdef __cplusplus
  37. "C"
  38. #endif
  39. double round (double);
  40. #ifdef _MSC_VER
  41. # pragma fenv_access (off)
  42. #endif
  43. int main()
  44. {
  45. /* 2^DBL_MANT_DIG. */
  46. static const double TWO_MANT_DIG =
  47. /* Assume DBL_MANT_DIG <= 5 * 31.
  48. Use the identity
  49. n = floor(n/5) + floor((n+1)/5) + ... + floor((n+4)/5). */
  50. (double) (1U << (DBL_MANT_DIG / 5))
  51. * (double) (1U << ((DBL_MANT_DIG + 1) / 5))
  52. * (double) (1U << ((DBL_MANT_DIG + 2) / 5))
  53. * (double) (1U << ((DBL_MANT_DIG + 3) / 5))
  54. * (double) (1U << ((DBL_MANT_DIG + 4) / 5));
  55. volatile double x = 0.5 - 0.5 / TWO_MANT_DIG;
  56. exit (x < 0.5 && round (x) != 0.0);
  57. }]])], [gl_cv_func_round_works=yes], [gl_cv_func_round_works=no],
  58. [case "$host_os" in
  59. netbsd* | aix*) gl_cv_func_round_works="guessing no";;
  60. *) gl_cv_func_round_works="guessing yes";;
  61. esac
  62. ])
  63. LIBS="$save_LIBS"
  64. ])
  65. case "$gl_cv_func_round_works" in
  66. *no) REPLACE_ROUND=1 ;;
  67. esac
  68. m4_ifdef([gl_FUNC_ROUND_IEEE], [
  69. if test $gl_round_required = ieee && test $REPLACE_ROUND = 0; then
  70. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  71. AC_CACHE_CHECK([whether round works according to ISO C 99 with IEC 60559],
  72. [gl_cv_func_round_ieee],
  73. [
  74. save_LIBS="$LIBS"
  75. LIBS="$LIBS $ROUND_LIBM"
  76. AC_RUN_IFELSE(
  77. [AC_LANG_SOURCE([[
  78. #ifndef __NO_MATH_INLINES
  79. # define __NO_MATH_INLINES 1 /* for glibc */
  80. #endif
  81. #include <math.h>
  82. extern
  83. #ifdef __cplusplus
  84. "C"
  85. #endif
  86. double round (double);
  87. ]gl_DOUBLE_MINUS_ZERO_CODE[
  88. ]gl_DOUBLE_SIGNBIT_CODE[
  89. static double dummy (double f) { return 0; }
  90. int main (int argc, char *argv[])
  91. {
  92. double (*my_round) (double) = argc ? round : dummy;
  93. /* Test whether round (-0.0) is -0.0. */
  94. if (signbitd (minus_zerod) && !signbitd (my_round (minus_zerod)))
  95. return 1;
  96. return 0;
  97. }
  98. ]])],
  99. [gl_cv_func_round_ieee=yes],
  100. [gl_cv_func_round_ieee=no],
  101. [case "$host_os" in
  102. # Guess yes on glibc systems.
  103. *-gnu*) gl_cv_func_round_ieee="guessing yes" ;;
  104. # If we don't know, assume the worst.
  105. *) gl_cv_func_round_ieee="guessing no" ;;
  106. esac
  107. ])
  108. LIBS="$save_LIBS"
  109. ])
  110. case "$gl_cv_func_round_ieee" in
  111. *yes) ;;
  112. *) REPLACE_ROUND=1 ;;
  113. esac
  114. fi
  115. ])
  116. else
  117. HAVE_ROUND=0
  118. HAVE_DECL_ROUND=0
  119. fi
  120. if test $HAVE_ROUND = 0 || test $REPLACE_ROUND = 1; then
  121. dnl Find libraries needed to link lib/round.c.
  122. gl_FUNC_FLOOR_LIBS
  123. gl_FUNC_CEIL_LIBS
  124. ROUND_LIBM=
  125. dnl Append $FLOOR_LIBM to ROUND_LIBM, avoiding gratuitous duplicates.
  126. case " $ROUND_LIBM " in
  127. *" $FLOOR_LIBM "*) ;;
  128. *) ROUND_LIBM="$ROUND_LIBM $FLOOR_LIBM" ;;
  129. esac
  130. dnl Append $CEIL_LIBM to ROUND_LIBM, avoiding gratuitous duplicates.
  131. case " $ROUND_LIBM " in
  132. *" $CEIL_LIBM "*) ;;
  133. *) ROUND_LIBM="$ROUND_LIBM $CEIL_LIBM" ;;
  134. esac
  135. fi
  136. AC_SUBST([ROUND_LIBM])
  137. ])