This is a question from my regular column. It is necessary to subtract 2 uint32_t so that the bytes are subtracted separately, and at the same time a - b = 0 if a < b . For example, 0x02.00.00 - 0x01.00.10 = 0x01.00.00

As always without if-s (ternary operators), simd instructions and other benefits of civilization.

  • For the last time, for some reason, you arranged an answer with the use of -(res <= x) , and from the point of view of the assembler, the operator <= is 100% IF. And with such hidden if, you can calmly check and subtract when necessary - Mike
  • About <= for the assembler did not know. Chose the most concise answer. - neko69

2 answers 2

 #include <stdio.h> #include <stdint.h> uint32_t bytes_dozu32(uint32_t x,uint32_t y) { uint32_t xr=x ^ y; uint32_t su=(x | 0x80808080)-(y & 0x7F7F7F7F);// Безопасно вычитаем младшие 7 бит байтов return ~( (xr | 0x7F7F7F7F) ^ su) & ((( // Объединяем разность 8х бит и младшие (~xr & su) | // 8е биты x/y равны - 8е биты su говорят, что не было переноса (xr & x)) & // 8e биты x/y НЕ равны - x > y если 8й бит x=1 0x80808080)>>7)*255; // Оставляем только 8е биты и распространяем их на весь байт } int main(void) { uint32_t x=0x027FED01; uint32_t y=0x01857E10; printf("%08x -\n%08x =\n",x,y); printf("%08x\n",bytes_dozu32(x,y)); } 

Result:

 027fed01 - 01857e10 = 01006f00 

    It seems the answer is already in question. Bytes separately? - means to decompose uint32 into 4 bytes. subtract 2 bytes of numbers in pairs (if the first is greater than the second, or 0). Then these byte differences, taking into account the weights, should be put in one 32 bit number

    If details are needed, decompose is bitwise & with acc. mask (0xff, 0xff00, 0xff0000 and 0xff000000) and shift to the right by 0, 8, 16 or 24 bits respectively. grouping together is multiplying partial sums by 1, 0x100, 0x10000 and 0x1000000, respectively, and adding these 4 pieces