Multiply-Add Constants Finder
The multiply-add method speeds up integer division by a known constant divisor by replacing it with a multiplication, addition, and shift. This tool implements a generalization of this method, which allows multiplication by a known constant rational number (i.e. a fraction) followed by a rounding function. E.g. .
Tool
/// Converts a value 0..=31 to 0..=255
/// by multiplying with 255/31 and then rounding.
fn convert_range(x: u8) -> u8 {
debug_assert!(x <= 31);
((x as u16 * 527 + 23) >> 6) as u8
}// Converts a value 0..=31 to 0..=255
// by multiplying with 255/31 and then rounding.
uint8_t convert_range(uint8_t x) {
assert(x <= 31);
return ((uint16_t)x * 527 + 23) >> 6;
}All solutions
s=6 f=527 a=23
Usage
This tool takes a problem (i.e. find multiply-add constants for for in the range ) and finds suitable constants.
Specify the parameters below and let this tool find suitable constants.
-
ris the rounding function. After multiplying by the fraction, the result is rarely an integer, so it needs to be rounded. Supported rounding functions are:round: round to nearest integer, rounding half away from zerofloor: round down to negative infinity,ceil: round up to positive infinity,
-
tanddare the numerator and denominator of the fraction to multiply by. -
uis the maximum input value (inclusive). Found constants are only valid for inputs .Use the "uN" buttons to quickly set the value for N-bit unsigned integers.
The tool will output an expression of the Best Solution. There are always infinitely many solutions, but this solution may allow additional compilers optimizations. C and Rust code implementing this solution are generated (some of the integer types used may require third-party libraries).
All solutions for the current problem can be viewed below. Solutions are given by their shift amount, factor, and addend.
Limitations
-
Certain problems are very computationally expensive to solve. In that case, this tool falls back to a solution that is known to be correct, but not necessarily optimal (=having the smallest s). This is indicated by a warning message.
-
While this tool support arbitrarily large integers as input, your browser may not like that. Number inputs may behave weirdly for numbers greater 4.5e+15 (2^52).