nan64.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * 64-bit IEEE not-a-number routines.
  3. * This is big/little-endian portable assuming that
  4. * the 64-bit doubles and 64-bit integers have the
  5. * same byte ordering.
  6. */
  7. #include "nan.h"
  8. #ifdef __APPLE__
  9. #define _NEEDLL
  10. #endif
  11. typedef unsigned long long uvlong;
  12. typedef unsigned long ulong;
  13. #ifdef _NEEDLL
  14. static uvlong uvnan = 0x7FF0000000000001LL;
  15. static uvlong uvinf = 0x7FF0000000000000LL;
  16. static uvlong uvneginf = 0xFFF0000000000000LL;
  17. #else
  18. static uvlong uvnan = 0x7FF0000000000001;
  19. static uvlong uvinf = 0x7FF0000000000000;
  20. static uvlong uvneginf = 0xFFF0000000000000;
  21. #endif
  22. double
  23. __NaN(void)
  24. {
  25. uvlong *p;
  26. /* gcc complains about "return *(double*)&uvnan;" */
  27. p = &uvnan;
  28. return *(double*)p;
  29. }
  30. int
  31. __isNaN(double d)
  32. {
  33. uvlong x;
  34. double *p;
  35. p = &d;
  36. x = *(uvlong*)p;
  37. return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
  38. }
  39. double
  40. __Inf(int sign)
  41. {
  42. uvlong *p;
  43. if(sign < 0)
  44. p = &uvinf;
  45. else
  46. p = &uvneginf;
  47. return *(double*)p;
  48. }
  49. int
  50. __isInf(double d, int sign)
  51. {
  52. uvlong x;
  53. double *p;
  54. p = &d;
  55. x = *(uvlong*)p;
  56. if(sign == 0)
  57. return x==uvinf || x==uvneginf;
  58. else if(sign > 0)
  59. return x==uvinf;
  60. else
  61. return x==uvneginf;
  62. }