I'm really not sure if this would make enough difference to be useful - but it's kinda neat. It's basically a template class that turns y = m * x / d into y = (c * x) >> n eg: fast_int_muldiv<int, 10, 3>::op( x ) it is an approximation only, and the larger PREC value you give, the more precise it is, and the larger integer it would need. So a decent precision would probably need a 64 bit integer. I would need to do experiments on the ESP32 to really get an idea. One thing it does do is turn a multiply and divide (like for imperial units) into 2 operations. //. constexpr unsigned floorlog2(unsigned x) { return x == 1 ? 0 : 1+floorlog2(x >> 1); } constexpr unsigned ceillog2(unsigned x) { return x == 1 ? 0 : floorlog2(x - 1) + 1; } /* Use a multiple and shift (right) to approximate a multiply and divide. * T - the intermediate type used. * M - The multiplier (1 is fine) * D - The divisor * PREC - The precision required for the operation. */ template<typename T, unsigned M, unsigned D, unsigned PREC=100> class fast_int_muldiv { public: static const uint8_t shift = ceillog2(D * PREC); // Gives the approx multiplier that fits with the chosen shift value . static const T mult = M* (((T(0x1) << shift)+(D>>1)) / D); // Perform the operation approx (val * M / D) static T op(T val) { // Make sure there is enough space (16bits) for a value. static_assert( (8 * sizeof(T)) >= (16 + shift + floorlog2(mult)), "Use a larger integer or smaller precision"); return ((val * mult) >> shift); } };