|
PebbleOS
|
Integer math macros and helpers. More...
Macros | |
| #define | MIN(a, b) (((a) < (b)) ? (a) : (b)) |
| Get the smaller of two values. | |
| #define | MAX(a, b) (((a) > (b)) ? (a) : (b)) |
| Get the larger of two values. | |
| #define | ABS(a) (((a) > 0) ? (a) : -1 * (a)) |
| Get the absolute value. | |
| #define | CLIP(n, min, max) ((n) < (min) ? (min) : ((n) > (max) ? (max) : (n))) |
| Clamp a value to a range. | |
| #define | ROUND(num, denom) (((num) + ((denom) / 2)) / (denom)) |
| Divide, rounding half up, for non-negative operands. | |
| #define | WITHIN(n, min, max) ((n) >= (min) && (n) <= (max)) |
| Check whether a value is within a closed range. | |
| #define | RANGE_WITHIN(n_min, n_max, min, max) ((n_min) >= (min) && (n_max) <= (max)) |
| Check whether a range is within another closed range. | |
| #define | DIVIDE_CEIL(num, denom) (((num) + ((denom) - 1)) / (denom)) |
| Divide, rounding up for positive results. | |
| #define | ROUND_TO_MOD_CEIL(val, mod) |
| Round a value away from zero to a multiple of a modulus. | |
| #define | ROUND_TO_MOD_CEIL_U(val, mod) ((((val) + ABS(ABS(mod) - 1)) / ABS(mod)) * ABS(mod)) |
| Round an unsigned value up to a multiple of a modulus. | |
| #define | IS_SIGNED(var) |
| Determine whether a variable is signed or not. | |
Functions | |
| int32_t | sign_extend (uint32_t a, int bits) |
| Sign-extend the low bits of a value. | |
| int32_t | serial_distance32 (uint32_t start, uint32_t end) |
| Compute the distance between two 32-bit serial numbers, handling wrap-around. | |
| int32_t | serial_distance (uint32_t start, uint32_t end, int bits) |
| Compute the distance between two serial numbers, handling wrap-around. | |
| int | ceil_log_two (uint32_t n) |
| Compute the base 2 logarithm, rounded up. | |
| int32_t | integer_sqrt (int64_t x) |
| Compute the integer square root with Newton's method. | |
| static bool | pbl_u32_add_overflow (uint32_t a, uint32_t b, uint32_t *result) |
| Add two 32-bit unsigned integers, detecting overflow. | |
| static bool | pbl_u32_mul_overflow (uint32_t a, uint32_t b, uint32_t *result) |
| Multiply two 32-bit unsigned integers, detecting overflow. | |
| static bool | pbl_size_add_overflow (size_t a, size_t b, size_t *result) |
| Add two sizes, detecting overflow. | |
| static bool | pbl_size_mul_overflow (size_t a, size_t b, size_t *result) |
| Multiply two sizes, detecting overflow. | |
| static int | positive_modulo (int i, int n) |
| Compute a modulo that is never negative. | |
| static int | distance_to_mod_boundary (int32_t i, uint16_t n) |
| Compute the distance from a value to the nearest multiple of a modulus. | |
| uint32_t | next_exponential_backoff (uint32_t *attempt, uint32_t initial_value, uint32_t max_value) |
| Compute the next interval of a bounded binary exponential backoff. | |
| uint32_t | gcd (uint32_t a, uint32_t b) |
| Compute the greatest common divisor of two numbers. | |
Integer math macros and helpers.
The macros evaluate their arguments more than once; do not pass expressions with side effects.
| #define ABS | ( | a | ) | (((a) > 0) ? (a) : -1 * (a)) |
Get the absolute value.
| a | Value. |
| #define CLIP | ( | n, | |
| min, | |||
| max | |||
| ) | ((n) < (min) ? (min) : ((n) > (max) ? (max) : (n))) |
Clamp a value to a range.
| n | Value. |
| min | Lower bound. |
| max | Upper bound. |
| #define DIVIDE_CEIL | ( | num, | |
| denom | |||
| ) | (((num) + ((denom) - 1)) / (denom)) |
Divide, rounding up for positive results.
Negative results round towards zero: DIVIDE_CEIL(3, 4) is 1 and DIVIDE_CEIL(-3, 4) is 0.
| num | Numerator. |
| denom | Denominator, positive. |
| #define IS_SIGNED | ( | var | ) |
Determine whether a variable is signed or not.
| var | The variable to evaluate. |
| #define MAX | ( | a, | |
| b | |||
| ) | (((a) > (b)) ? (a) : (b)) |
Get the larger of two values.
| a | First value. |
| b | Second value. |
| #define MIN | ( | a, | |
| b | |||
| ) | (((a) < (b)) ? (a) : (b)) |
Get the smaller of two values.
| a | First value. |
| b | Second value. |
| #define RANGE_WITHIN | ( | n_min, | |
| n_max, | |||
| min, | |||
| max | |||
| ) | ((n_min) >= (min) && (n_max) <= (max)) |
Check whether a range is within another closed range.
| n_min | Lower bound of the inner range. |
| n_max | Upper bound of the inner range. |
| min | Lower bound of the outer range, included. |
| max | Upper bound of the outer range, included. |
| #define ROUND | ( | num, | |
| denom | |||
| ) | (((num) + ((denom) / 2)) / (denom)) |
Divide, rounding half up, for non-negative operands.
| num | Numerator. |
| denom | Denominator. |
| #define ROUND_TO_MOD_CEIL | ( | val, | |
| mod | |||
| ) |
Round a value away from zero to a multiple of a modulus.
ROUND_TO_MOD_CEIL(152, 32) is 160 and ROUND_TO_MOD_CEIL(-32, 90) is -90.
| val | Value. |
| mod | Modulus; its sign is ignored. |
Round an unsigned value up to a multiple of a modulus.
ROUND_TO_MOD_CEIL_U(152, 32) is 160.
| val | Value. |
| mod | Modulus; its sign is ignored. |
| #define WITHIN | ( | n, | |
| min, | |||
| max | |||
| ) | ((n) >= (min) && (n) <= (max)) |
Check whether a value is within a closed range.
| n | Value. |
| min | Lower bound, included. |
| max | Upper bound, included. |
| int ceil_log_two | ( | uint32_t | n | ) |
Compute the base 2 logarithm, rounded up.
| n | Value, greater than 0. |
n)).
|
inlinestatic |
Compute the distance from a value to the nearest multiple of a modulus.
For angles, the smallest difference between two angles is distance_to_mod_boundary(a - b, 360).
| i | Value. |
| n | Modulus, positive. |
n / 2. References ABS, and positive_modulo().
| uint32_t gcd | ( | uint32_t | a, |
| uint32_t | b | ||
| ) |
Compute the greatest common divisor of two numbers.
| a | First number. |
| b | Second number. |
| int32_t integer_sqrt | ( | int64_t | x | ) |
Compute the integer square root with Newton's method.
| x | Value. |
x)), 0 for negative values. | uint32_t next_exponential_backoff | ( | uint32_t * | attempt, |
| uint32_t | initial_value, | ||
| uint32_t | max_value | ||
| ) |
Compute the next interval of a bounded binary exponential backoff.
| [in,out] | attempt | Retries performed so far, incremented by the call. |
| initial_value | First interval; later ones are this multiplied by a power of 2. | |
| max_value | Maximum interval returned. |
initial_value * 2^attempt capped to max_value.
|
inlinestatic |
Add two sizes, detecting overflow.
| a | First operand. | |
| b | Second operand. | |
| [out] | result | Sum, wrapped around on overflow. |
References PBL_ADD_OVERFLOW.
|
inlinestatic |
Multiply two sizes, detecting overflow.
| a | First operand. | |
| b | Second operand. | |
| [out] | result | Product, wrapped around on overflow. |
References PBL_MUL_OVERFLOW.
|
inlinestatic |
Add two 32-bit unsigned integers, detecting overflow.
| a | First operand. | |
| b | Second operand. | |
| [out] | result | Sum, wrapped around on overflow. |
References PBL_ADD_OVERFLOW.
|
inlinestatic |
Multiply two 32-bit unsigned integers, detecting overflow.
| a | First operand. | |
| b | Second operand. | |
| [out] | result | Product, wrapped around on overflow. |
References PBL_MUL_OVERFLOW.
|
inlinestatic |
Compute a modulo that is never negative.
| i | Dividend. |
| n | Divisor, positive. |
i mod n, in [0, n). Referenced by distance_to_mod_boundary().
| int32_t serial_distance | ( | uint32_t | start, |
| uint32_t | end, | ||
| int | bits | ||
| ) |
Compute the distance between two serial numbers, handling wrap-around.
| start | Start value. |
| end | End value. |
| bits | Number of valid bits in start and end. |
end - start, using serial number arithmetic (RFC 1982). | int32_t serial_distance32 | ( | uint32_t | start, |
| uint32_t | end | ||
| ) |
Compute the distance between two 32-bit serial numbers, handling wrap-around.
| start | Start value. |
| end | End value. |
end - start, using serial number arithmetic (RFC 1982). | int32_t sign_extend | ( | uint32_t | a, |
| int | bits | ||
| ) |
Sign-extend the low bits of a value.
| a | Value; bits above bits are ignored. |
| bits | Width of the signed value, 1 to 32. |