frexp.c 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include <u.h>
  2. #include <libc.h>
  3. #define DEEPS ".5*2^-1073"
  4. #define DENEPS "-.5*2^-1073"
  5. #define DEPINF "+Inf*2^0"
  6. #define DENAN "NaN*2^0"
  7. jmp_buf errj;
  8. char *err;
  9. int fail = 0;
  10. void
  11. catcher(void *u, char *s)
  12. {
  13. err = 0;
  14. if(strncmp(s, "sys: fp:", 8) == 0){
  15. err = s;
  16. notejmp(u, errj, 0);
  17. }
  18. noted(NDFLT);
  19. }
  20. void
  21. decomp(double d, int *exp, char *s)
  22. {
  23. double m;
  24. m = frexp(d, exp);
  25. print("Expected decomposition: %s\n", s);
  26. print("Actual decomposition: %g*2^%d\n", m, *exp);
  27. if(isNaN(d)){
  28. if(*exp != 0 || !isNaN(m))
  29. fail = 1;
  30. return;
  31. }
  32. if(isInf(d, 1)){
  33. if(*exp != 0 || !isInf(m, 1))
  34. fail = 1;
  35. return;
  36. }
  37. if(fabs(d - ldexp(m, *exp)) > 4e-16)
  38. fail = 1;
  39. }
  40. void
  41. main(void)
  42. {
  43. double eps, neps;
  44. int exp;
  45. err = 0;
  46. notify(catcher);
  47. setjmp(errj);
  48. if(err){
  49. fprint(2, "%s\n", err);
  50. exits("FAIL");
  51. }
  52. eps = ldexp(1, -1074);
  53. neps = ldexp(-1, -1074);
  54. print("Smallest Positive Double: %g\n", eps);
  55. decomp(eps, &exp, DEEPS);
  56. print("Largest Negative Double: %g\n", neps);
  57. decomp(neps, &exp, DENEPS);
  58. print("Positive infinity: %g\n", Inf(1));
  59. decomp(Inf(1), &exp, DEPINF);
  60. print("NaN: %g\n", NaN());
  61. decomp(NaN(), &exp, DENAN);
  62. if(fail)
  63. exits("FAIL");
  64. }