Math behind gcc9+ modulus optimizations












5














Background



I was playing with prime numbers in c, when I stumbled upon a new optimization in gcc trunk (will be version 9.x) that optimizes a modulus comparison to 0 into an integer multiply and comparison using magic numbers. In other words x%prime==0 becomes x*Magic_mul<=Magic_cmp



_Bool mod(unsigned x){return x % Constant == 0;}

mod:
imul edi, edi, Magic_mul
cmp edi, Magic_cmp
setbe al


Details



Based on seeing the asm output, it does these optimizations for all integers (well, primes at least) I converted them to hex to help see the patterns, but its not immediately obvious at the moment.



//32bit examples for _Bool mod_n(unsigned x){return x%n==0;};
//note: parameter is unsigned but it becomes a signed multiply
x%3==0; // x*0xAAAAAAAB <= 0x55555555
x%5==0; // x*0xCCCCCCCD <= 0x33333333
x%7==0; // x*0xB6DB6DB7 <= 0x24924924
x%11==0; // x*0xBA2E8BA3 <= 0x1745D174
x%13==0; // x*0xC4EC4EC5 <= 0x13B13B13
x%17==0; // x*0xF0F0F0F1 <= 0x0F0F0F0F
x%19==0; // x*0x286BCA1B <= 0x0D79435E
x%23==0; // x*0xE9BD37A7 <= 0x0B21642C
x%29==0; // x*0x4F72C235 <= 0x08D3DCB0
x%31==0; // x*0xBDEF7BDF <= 0x08421084
x%37==0; // x*0x914C1BAD <= 0x06EB3E45
x%41==0; // x*0xC18F9C19 <= 0x063E7063
x%43==0; // x*0x2FA0BE83 <= 0x05F417D0
x%47==0; // x*0x677D46CF <= 0x0572620A
x%53==0; // x*0x8C13521D <= 0x04D4873E
x%59==0; // x*0xA08AD8F3 <= 0x0456C797
x%61==0; // x*0xC10C9715 <= 0x04325C53
x%67==0; // x*0x07A44C6B <= 0x03D22635
x%71==0; // x*0xE327A977 <= 0x039B0AD1
x%73==0; // x*0xC7E3F1F9 <= 0x0381C0E0
x%79==0; // x*0x613716AF <= 0x033D91D2
x%83==0; // x*0x2B2E43DB <= 0x03159721
x%89==0; // x*0xFA3F47E9 <= 0x02E05C0B
x%97==0; // x*0x5F02A3A1 <= 0x02A3A0FD
///...and even up to 64bit
x%4294967291==0; //x*0x70A3D70A33333333 <= 0x100000005


I checked hacker's delight "INTEGER DIVISION BY CONSTANTS" and it seems like this may be a special case of remainder by multiplication and right shift, but I'm not sure. There is a form on hacker's delight that calculates these same multiplier constants, so that seems promising. I'm guessing the magic comparison constant replaces the shift and compare to zero, but I am having trouble visualizing the 2s complement and whether the shift is arithmetic or logical.



Question



Is there some math behind this or were the numbers determined some other way using the binary representation?



Implications



Since this is simple integer multiply and comparison this could drastically speed up (or reduce memory footprint of) checking for prime using vector extensions/intrinsics. If the math could be extended beyond 64 bits, it could possibly make finding large Big-Number primes much faster?










share|improve this question






















  • For division.
    – user202729
    Nov 21 '18 at 15:06










  • Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
    – user202729
    Nov 21 '18 at 15:08


















5














Background



I was playing with prime numbers in c, when I stumbled upon a new optimization in gcc trunk (will be version 9.x) that optimizes a modulus comparison to 0 into an integer multiply and comparison using magic numbers. In other words x%prime==0 becomes x*Magic_mul<=Magic_cmp



_Bool mod(unsigned x){return x % Constant == 0;}

mod:
imul edi, edi, Magic_mul
cmp edi, Magic_cmp
setbe al


Details



Based on seeing the asm output, it does these optimizations for all integers (well, primes at least) I converted them to hex to help see the patterns, but its not immediately obvious at the moment.



//32bit examples for _Bool mod_n(unsigned x){return x%n==0;};
//note: parameter is unsigned but it becomes a signed multiply
x%3==0; // x*0xAAAAAAAB <= 0x55555555
x%5==0; // x*0xCCCCCCCD <= 0x33333333
x%7==0; // x*0xB6DB6DB7 <= 0x24924924
x%11==0; // x*0xBA2E8BA3 <= 0x1745D174
x%13==0; // x*0xC4EC4EC5 <= 0x13B13B13
x%17==0; // x*0xF0F0F0F1 <= 0x0F0F0F0F
x%19==0; // x*0x286BCA1B <= 0x0D79435E
x%23==0; // x*0xE9BD37A7 <= 0x0B21642C
x%29==0; // x*0x4F72C235 <= 0x08D3DCB0
x%31==0; // x*0xBDEF7BDF <= 0x08421084
x%37==0; // x*0x914C1BAD <= 0x06EB3E45
x%41==0; // x*0xC18F9C19 <= 0x063E7063
x%43==0; // x*0x2FA0BE83 <= 0x05F417D0
x%47==0; // x*0x677D46CF <= 0x0572620A
x%53==0; // x*0x8C13521D <= 0x04D4873E
x%59==0; // x*0xA08AD8F3 <= 0x0456C797
x%61==0; // x*0xC10C9715 <= 0x04325C53
x%67==0; // x*0x07A44C6B <= 0x03D22635
x%71==0; // x*0xE327A977 <= 0x039B0AD1
x%73==0; // x*0xC7E3F1F9 <= 0x0381C0E0
x%79==0; // x*0x613716AF <= 0x033D91D2
x%83==0; // x*0x2B2E43DB <= 0x03159721
x%89==0; // x*0xFA3F47E9 <= 0x02E05C0B
x%97==0; // x*0x5F02A3A1 <= 0x02A3A0FD
///...and even up to 64bit
x%4294967291==0; //x*0x70A3D70A33333333 <= 0x100000005


I checked hacker's delight "INTEGER DIVISION BY CONSTANTS" and it seems like this may be a special case of remainder by multiplication and right shift, but I'm not sure. There is a form on hacker's delight that calculates these same multiplier constants, so that seems promising. I'm guessing the magic comparison constant replaces the shift and compare to zero, but I am having trouble visualizing the 2s complement and whether the shift is arithmetic or logical.



Question



Is there some math behind this or were the numbers determined some other way using the binary representation?



Implications



Since this is simple integer multiply and comparison this could drastically speed up (or reduce memory footprint of) checking for prime using vector extensions/intrinsics. If the math could be extended beyond 64 bits, it could possibly make finding large Big-Number primes much faster?










share|improve this question






















  • For division.
    – user202729
    Nov 21 '18 at 15:06










  • Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
    – user202729
    Nov 21 '18 at 15:08
















5












5








5


2





Background



I was playing with prime numbers in c, when I stumbled upon a new optimization in gcc trunk (will be version 9.x) that optimizes a modulus comparison to 0 into an integer multiply and comparison using magic numbers. In other words x%prime==0 becomes x*Magic_mul<=Magic_cmp



_Bool mod(unsigned x){return x % Constant == 0;}

mod:
imul edi, edi, Magic_mul
cmp edi, Magic_cmp
setbe al


Details



Based on seeing the asm output, it does these optimizations for all integers (well, primes at least) I converted them to hex to help see the patterns, but its not immediately obvious at the moment.



//32bit examples for _Bool mod_n(unsigned x){return x%n==0;};
//note: parameter is unsigned but it becomes a signed multiply
x%3==0; // x*0xAAAAAAAB <= 0x55555555
x%5==0; // x*0xCCCCCCCD <= 0x33333333
x%7==0; // x*0xB6DB6DB7 <= 0x24924924
x%11==0; // x*0xBA2E8BA3 <= 0x1745D174
x%13==0; // x*0xC4EC4EC5 <= 0x13B13B13
x%17==0; // x*0xF0F0F0F1 <= 0x0F0F0F0F
x%19==0; // x*0x286BCA1B <= 0x0D79435E
x%23==0; // x*0xE9BD37A7 <= 0x0B21642C
x%29==0; // x*0x4F72C235 <= 0x08D3DCB0
x%31==0; // x*0xBDEF7BDF <= 0x08421084
x%37==0; // x*0x914C1BAD <= 0x06EB3E45
x%41==0; // x*0xC18F9C19 <= 0x063E7063
x%43==0; // x*0x2FA0BE83 <= 0x05F417D0
x%47==0; // x*0x677D46CF <= 0x0572620A
x%53==0; // x*0x8C13521D <= 0x04D4873E
x%59==0; // x*0xA08AD8F3 <= 0x0456C797
x%61==0; // x*0xC10C9715 <= 0x04325C53
x%67==0; // x*0x07A44C6B <= 0x03D22635
x%71==0; // x*0xE327A977 <= 0x039B0AD1
x%73==0; // x*0xC7E3F1F9 <= 0x0381C0E0
x%79==0; // x*0x613716AF <= 0x033D91D2
x%83==0; // x*0x2B2E43DB <= 0x03159721
x%89==0; // x*0xFA3F47E9 <= 0x02E05C0B
x%97==0; // x*0x5F02A3A1 <= 0x02A3A0FD
///...and even up to 64bit
x%4294967291==0; //x*0x70A3D70A33333333 <= 0x100000005


I checked hacker's delight "INTEGER DIVISION BY CONSTANTS" and it seems like this may be a special case of remainder by multiplication and right shift, but I'm not sure. There is a form on hacker's delight that calculates these same multiplier constants, so that seems promising. I'm guessing the magic comparison constant replaces the shift and compare to zero, but I am having trouble visualizing the 2s complement and whether the shift is arithmetic or logical.



Question



Is there some math behind this or were the numbers determined some other way using the binary representation?



Implications



Since this is simple integer multiply and comparison this could drastically speed up (or reduce memory footprint of) checking for prime using vector extensions/intrinsics. If the math could be extended beyond 64 bits, it could possibly make finding large Big-Number primes much faster?










share|improve this question













Background



I was playing with prime numbers in c, when I stumbled upon a new optimization in gcc trunk (will be version 9.x) that optimizes a modulus comparison to 0 into an integer multiply and comparison using magic numbers. In other words x%prime==0 becomes x*Magic_mul<=Magic_cmp



_Bool mod(unsigned x){return x % Constant == 0;}

mod:
imul edi, edi, Magic_mul
cmp edi, Magic_cmp
setbe al


Details



Based on seeing the asm output, it does these optimizations for all integers (well, primes at least) I converted them to hex to help see the patterns, but its not immediately obvious at the moment.



//32bit examples for _Bool mod_n(unsigned x){return x%n==0;};
//note: parameter is unsigned but it becomes a signed multiply
x%3==0; // x*0xAAAAAAAB <= 0x55555555
x%5==0; // x*0xCCCCCCCD <= 0x33333333
x%7==0; // x*0xB6DB6DB7 <= 0x24924924
x%11==0; // x*0xBA2E8BA3 <= 0x1745D174
x%13==0; // x*0xC4EC4EC5 <= 0x13B13B13
x%17==0; // x*0xF0F0F0F1 <= 0x0F0F0F0F
x%19==0; // x*0x286BCA1B <= 0x0D79435E
x%23==0; // x*0xE9BD37A7 <= 0x0B21642C
x%29==0; // x*0x4F72C235 <= 0x08D3DCB0
x%31==0; // x*0xBDEF7BDF <= 0x08421084
x%37==0; // x*0x914C1BAD <= 0x06EB3E45
x%41==0; // x*0xC18F9C19 <= 0x063E7063
x%43==0; // x*0x2FA0BE83 <= 0x05F417D0
x%47==0; // x*0x677D46CF <= 0x0572620A
x%53==0; // x*0x8C13521D <= 0x04D4873E
x%59==0; // x*0xA08AD8F3 <= 0x0456C797
x%61==0; // x*0xC10C9715 <= 0x04325C53
x%67==0; // x*0x07A44C6B <= 0x03D22635
x%71==0; // x*0xE327A977 <= 0x039B0AD1
x%73==0; // x*0xC7E3F1F9 <= 0x0381C0E0
x%79==0; // x*0x613716AF <= 0x033D91D2
x%83==0; // x*0x2B2E43DB <= 0x03159721
x%89==0; // x*0xFA3F47E9 <= 0x02E05C0B
x%97==0; // x*0x5F02A3A1 <= 0x02A3A0FD
///...and even up to 64bit
x%4294967291==0; //x*0x70A3D70A33333333 <= 0x100000005


I checked hacker's delight "INTEGER DIVISION BY CONSTANTS" and it seems like this may be a special case of remainder by multiplication and right shift, but I'm not sure. There is a form on hacker's delight that calculates these same multiplier constants, so that seems promising. I'm guessing the magic comparison constant replaces the shift and compare to zero, but I am having trouble visualizing the 2s complement and whether the shift is arithmetic or logical.



Question



Is there some math behind this or were the numbers determined some other way using the binary representation?



Implications



Since this is simple integer multiply and comparison this could drastically speed up (or reduce memory footprint of) checking for prime using vector extensions/intrinsics. If the math could be extended beyond 64 bits, it could possibly make finding large Big-Number primes much faster?







c math compiler-optimization modulus






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 14:53









technosaurustechnosaurus

6,01212042




6,01212042












  • For division.
    – user202729
    Nov 21 '18 at 15:06










  • Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
    – user202729
    Nov 21 '18 at 15:08




















  • For division.
    – user202729
    Nov 21 '18 at 15:06










  • Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
    – user202729
    Nov 21 '18 at 15:08


















For division.
– user202729
Nov 21 '18 at 15:06




For division.
– user202729
Nov 21 '18 at 15:06












Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
– user202729
Nov 21 '18 at 15:08






Re implication: If you want to find larger primes, usually you just switch to a better primality check algorithm (stackoverflow.com/questions/4493645/fastest-primality-test), which doesn't have much to do with the main question.
– user202729
Nov 21 '18 at 15:08














1 Answer
1






active

oldest

votes


















2














Take 3, for instance.



0xAB * 3 = 0x201, thus, modulo 0x100, 0xAB is 1 / 3, and, inversely, 0xAB * 3 ≡ 1.



Any 8-bit unsigned integer n can be represented as n = 3*k + r, r < 3, and n is at most 0x55 (decimal 85, integral part of 255 / 3).



So we have options:




  1. r = 0 ⇒ n * 0xAB = 3k * 0xAB = k * (3 * 0xAB) ≡ k * 1 = k ≤ 0x55.


  2. r = 1 ⇒ n * 0xAB = 3k * 0xAB + 0xAB; since 3k * 0xAB is at most 0x55 (mod 0x100), adding it to 0xAB won't overflow, so 3k * 0xAB + 0xAB ≥ 0xAB > 0x55.


  3. r = 2 ⇒ n * 0xAB = 3k * 0xAB + 0x156 ≡ 3k * 0xAB + 0x56 ≥ 0x56 > 0x55 (same as 2.)







share|improve this answer





















  • Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
    – technosaurus
    Nov 21 '18 at 15:30










  • Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
    – bipll
    Nov 21 '18 at 15:47











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414711%2fmath-behind-gcc9-modulus-optimizations%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Take 3, for instance.



0xAB * 3 = 0x201, thus, modulo 0x100, 0xAB is 1 / 3, and, inversely, 0xAB * 3 ≡ 1.



Any 8-bit unsigned integer n can be represented as n = 3*k + r, r < 3, and n is at most 0x55 (decimal 85, integral part of 255 / 3).



So we have options:




  1. r = 0 ⇒ n * 0xAB = 3k * 0xAB = k * (3 * 0xAB) ≡ k * 1 = k ≤ 0x55.


  2. r = 1 ⇒ n * 0xAB = 3k * 0xAB + 0xAB; since 3k * 0xAB is at most 0x55 (mod 0x100), adding it to 0xAB won't overflow, so 3k * 0xAB + 0xAB ≥ 0xAB > 0x55.


  3. r = 2 ⇒ n * 0xAB = 3k * 0xAB + 0x156 ≡ 3k * 0xAB + 0x56 ≥ 0x56 > 0x55 (same as 2.)







share|improve this answer





















  • Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
    – technosaurus
    Nov 21 '18 at 15:30










  • Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
    – bipll
    Nov 21 '18 at 15:47
















2














Take 3, for instance.



0xAB * 3 = 0x201, thus, modulo 0x100, 0xAB is 1 / 3, and, inversely, 0xAB * 3 ≡ 1.



Any 8-bit unsigned integer n can be represented as n = 3*k + r, r < 3, and n is at most 0x55 (decimal 85, integral part of 255 / 3).



So we have options:




  1. r = 0 ⇒ n * 0xAB = 3k * 0xAB = k * (3 * 0xAB) ≡ k * 1 = k ≤ 0x55.


  2. r = 1 ⇒ n * 0xAB = 3k * 0xAB + 0xAB; since 3k * 0xAB is at most 0x55 (mod 0x100), adding it to 0xAB won't overflow, so 3k * 0xAB + 0xAB ≥ 0xAB > 0x55.


  3. r = 2 ⇒ n * 0xAB = 3k * 0xAB + 0x156 ≡ 3k * 0xAB + 0x56 ≥ 0x56 > 0x55 (same as 2.)







share|improve this answer





















  • Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
    – technosaurus
    Nov 21 '18 at 15:30










  • Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
    – bipll
    Nov 21 '18 at 15:47














2












2








2






Take 3, for instance.



0xAB * 3 = 0x201, thus, modulo 0x100, 0xAB is 1 / 3, and, inversely, 0xAB * 3 ≡ 1.



Any 8-bit unsigned integer n can be represented as n = 3*k + r, r < 3, and n is at most 0x55 (decimal 85, integral part of 255 / 3).



So we have options:




  1. r = 0 ⇒ n * 0xAB = 3k * 0xAB = k * (3 * 0xAB) ≡ k * 1 = k ≤ 0x55.


  2. r = 1 ⇒ n * 0xAB = 3k * 0xAB + 0xAB; since 3k * 0xAB is at most 0x55 (mod 0x100), adding it to 0xAB won't overflow, so 3k * 0xAB + 0xAB ≥ 0xAB > 0x55.


  3. r = 2 ⇒ n * 0xAB = 3k * 0xAB + 0x156 ≡ 3k * 0xAB + 0x56 ≥ 0x56 > 0x55 (same as 2.)







share|improve this answer












Take 3, for instance.



0xAB * 3 = 0x201, thus, modulo 0x100, 0xAB is 1 / 3, and, inversely, 0xAB * 3 ≡ 1.



Any 8-bit unsigned integer n can be represented as n = 3*k + r, r < 3, and n is at most 0x55 (decimal 85, integral part of 255 / 3).



So we have options:




  1. r = 0 ⇒ n * 0xAB = 3k * 0xAB = k * (3 * 0xAB) ≡ k * 1 = k ≤ 0x55.


  2. r = 1 ⇒ n * 0xAB = 3k * 0xAB + 0xAB; since 3k * 0xAB is at most 0x55 (mod 0x100), adding it to 0xAB won't overflow, so 3k * 0xAB + 0xAB ≥ 0xAB > 0x55.


  3. r = 2 ⇒ n * 0xAB = 3k * 0xAB + 0x156 ≡ 3k * 0xAB + 0x56 ≥ 0x56 > 0x55 (same as 2.)








share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 '18 at 15:19









bipllbipll

7,9711825




7,9711825












  • Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
    – technosaurus
    Nov 21 '18 at 15:30










  • Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
    – bipll
    Nov 21 '18 at 15:47


















  • Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
    – technosaurus
    Nov 21 '18 at 15:30










  • Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
    – bipll
    Nov 21 '18 at 15:47
















Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
– technosaurus
Nov 21 '18 at 15:30




Your math looks sound and seems to follow with the other documentation of this concept. I think I just need to grind out a few examples in binary notation to follow it (or get some sleep so I can do the hex->binary in my head). I was also hoping to figure out the math to get the comparison constants (which may be obvious once I can visualize it)
– technosaurus
Nov 21 '18 at 15:30












Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
– bipll
Nov 21 '18 at 15:47




Well, constants are quite straightforward, 0xAB is simply 1/3 and 0x55 is the highest floor of n/3 for a 8-bit n. Implications follow. :)
– bipll
Nov 21 '18 at 15:47


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414711%2fmath-behind-gcc9-modulus-optimizations%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen