nan64.c 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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 <u.h>
  8. #include <libc.h>
  9. #include "fmtdef.h"
  10. #if defined (__APPLE__) || (__powerpc__)
  11. #define _NEEDLL
  12. #endif
  13. static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001;
  14. static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000;
  15. static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
  16. double
  17. __NaN(void)
  18. {
  19. uvlong *p;
  20. /* gcc complains about "return *(double*)&uvnan;" */
  21. p = &uvnan;
  22. return *(double*)p;
  23. }
  24. int
  25. __isNaN(double d)
  26. {
  27. uvlong x;
  28. double *p;
  29. p = &d;
  30. x = *(uvlong*)p;
  31. return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
  32. }
  33. double
  34. __Inf(int sign)
  35. {
  36. uvlong *p;
  37. if(sign < 0)
  38. p = &uvinf;
  39. else
  40. p = &uvneginf;
  41. return *(double*)p;
  42. }
  43. int
  44. __isInf(double d, int sign)
  45. {
  46. uvlong x;
  47. double *p;
  48. p = &d;
  49. x = *(uvlong*)p;
  50. if(sign == 0)
  51. return x==uvinf || x==uvneginf;
  52. else if(sign > 0)
  53. return x==uvinf;
  54. else
  55. return x==uvneginf;
  56. }