muldiv.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "lib/intmath/muldiv.h"
  6. #include "lib/err/torerr.h"
  7. #include <stdlib.h>
  8. /** Return the lowest x such that x is at least <b>number</b>, and x modulo
  9. * <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
  10. * UINT_MAX. Asserts if divisor is zero. */
  11. unsigned
  12. round_to_next_multiple_of(unsigned number, unsigned divisor)
  13. {
  14. raw_assert(divisor > 0);
  15. if (UINT_MAX - divisor + 1 < number)
  16. return UINT_MAX;
  17. number += divisor - 1;
  18. number -= number % divisor;
  19. return number;
  20. }
  21. /** Return the lowest x such that x is at least <b>number</b>, and x modulo
  22. * <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
  23. * UINT32_MAX. Asserts if divisor is zero. */
  24. uint32_t
  25. round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
  26. {
  27. raw_assert(divisor > 0);
  28. if (UINT32_MAX - divisor + 1 < number)
  29. return UINT32_MAX;
  30. number += divisor - 1;
  31. number -= number % divisor;
  32. return number;
  33. }
  34. /** Return the lowest x such that x is at least <b>number</b>, and x modulo
  35. * <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
  36. * UINT64_MAX. Asserts if divisor is zero. */
  37. uint64_t
  38. round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
  39. {
  40. raw_assert(divisor > 0);
  41. if (UINT64_MAX - divisor + 1 < number)
  42. return UINT64_MAX;
  43. number += divisor - 1;
  44. number -= number % divisor;
  45. return number;
  46. }
  47. /* Helper: return greatest common divisor of a,b */
  48. static uint64_t
  49. gcd64(uint64_t a, uint64_t b)
  50. {
  51. while (b) {
  52. uint64_t t = b;
  53. b = a % b;
  54. a = t;
  55. }
  56. return a;
  57. }
  58. /* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
  59. * Requires that the denominator is greater than 0. */
  60. void
  61. simplify_fraction64(uint64_t *numer, uint64_t *denom)
  62. {
  63. raw_assert(denom);
  64. uint64_t gcd = gcd64(*numer, *denom);
  65. *numer /= gcd;
  66. *denom /= gcd;
  67. }