2021-07-19 21:55:20 +00:00
|
|
|
|
#if 0
|
|
|
|
|
/*─────────────────────────────────────────────────────────────────╗
|
|
|
|
|
│ To the extent possible under law, Justine Tunney has waived │
|
|
|
|
|
│ all copyright and related or neighboring rights to this file, │
|
|
|
|
|
│ as it is written in the following disclaimers: │
|
|
|
|
|
│ • http://unlicense.org/ │
|
|
|
|
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
|
|
|
|
╚─────────────────────────────────────────────────────────────────*/
|
|
|
|
|
#endif
|
|
|
|
|
#include "libc/stdio/stdio.h"
|
|
|
|
|
#include "libc/testlib/ezbench.h"
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @fileoverview Fast Modulus Using Multiplication Tutorial
|
|
|
|
|
*
|
|
|
|
|
* Expected program output:
|
|
|
|
|
*
|
|
|
|
|
* 23 / 3 = 7
|
|
|
|
|
* 0x5555555555555556 1 1
|
|
|
|
|
* modulus l: 15𝑐 5𝑛𝑠
|
|
|
|
|
* fastmod l: 4𝑐 1𝑛𝑠
|
|
|
|
|
* precomp l: 18𝑐 6𝑛𝑠
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
struct Modulus {
|
|
|
|
|
uint64_t c;
|
|
|
|
|
uint64_t d;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Modulus GetModulus(uint64_t d) {
|
|
|
|
|
return (struct Modulus){0xFFFFFFFFFFFFFFFFull / d + 1, d};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t Modulus(uint64_t x, struct Modulus m) {
|
|
|
|
|
return ((uint128_t)(m.c * x) * m.d) >> 64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
2021-08-10 20:38:27 +00:00
|
|
|
|
printf("%#lx %% %d = %d\n", 0x23, 3, Modulus(23, GetModulus(3)));
|
|
|
|
|
printf("%#lx %% %d = %d\n", 0x123, 17, Modulus(0x123, GetModulus(17)));
|
2021-07-19 21:55:20 +00:00
|
|
|
|
volatile struct Modulus v = GetModulus(3);
|
|
|
|
|
volatile uint64_t x = 23, y = 3, z;
|
|
|
|
|
EZBENCH2("modulus", donothing, z = x % y);
|
|
|
|
|
EZBENCH2("fastmod", donothing, z = Modulus(x, v));
|
|
|
|
|
EZBENCH2("precomp", donothing, v = GetModulus(y));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|