cosmopolitan/examples/fastmod.c

49 lines
1.8 KiB
C
Raw Normal View History

#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[]) {
printf("%lx %% %d = %d\n", 3, 23, Modulus(23, GetModulus(3)));
printf("%lx %% %d = %d\n", 3, 23,
Modulus(0xf5bd76d4c3c91f47, GetModulus(34)));
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;
}