difftime.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. ** This file is in the public domain, so clarified as of
  3. ** 1996-06-05 by Arthur David Olson.
  4. */
  5. #ifndef lint
  6. #ifndef NOID
  7. static char elsieid[] = "%W%";
  8. #endif /* !defined NOID */
  9. #endif /* !defined lint */
  10. /*LINTLIBRARY*/
  11. #include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
  12. double
  13. difftime(time1, time0)
  14. const time_t time1;
  15. const time_t time0;
  16. {
  17. /*
  18. ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
  19. ** (assuming that the larger type has more precision).
  20. ** This is the common real-world case circa 2004.
  21. */
  22. if (sizeof (double) > sizeof (time_t))
  23. return (double) time1 - (double) time0;
  24. if (!TYPE_INTEGRAL(time_t)) {
  25. /*
  26. ** time_t is floating.
  27. */
  28. return time1 - time0;
  29. }
  30. if (!TYPE_SIGNED(time_t)) {
  31. /*
  32. ** time_t is integral and unsigned.
  33. ** The difference of two unsigned values can't overflow
  34. ** if the minuend is greater than or equal to the subtrahend.
  35. */
  36. if (time1 >= time0)
  37. return time1 - time0;
  38. else return -((double) (time0 - time1));
  39. }
  40. /*
  41. ** time_t is integral and signed.
  42. ** Handle cases where both time1 and time0 have the same sign
  43. ** (meaning that their difference cannot overflow).
  44. */
  45. if ((time1 < 0) == (time0 < 0))
  46. return time1 - time0;
  47. /*
  48. ** time1 and time0 have opposite signs.
  49. ** Punt if unsigned long is too narrow.
  50. */
  51. if (sizeof (unsigned long) < sizeof (time_t))
  52. return (double) time1 - (double) time0;
  53. /*
  54. ** Stay calm...decent optimizers will eliminate the complexity below.
  55. */
  56. if (time1 >= 0 /* && time0 < 0 */)
  57. return (unsigned long) time1 +
  58. (unsigned long) (-(time0 + 1)) + 1;
  59. return -(double) ((unsigned long) time0 +
  60. (unsigned long) (-(time1 + 1)) + 1);
  61. }