muldiv.c 2.1 KB

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