Unsigned char overflow with subtraction

I am trying to understand how unsigned overflow works with subtraction, so I wrote the following test to try:

#include<stdio.h>
#include<stdlib.h>

unsigned char minWrap(unsigned char a, unsigned char b) {
    return a > b ? a - b : a + (0xff - b) + 1;
}

int main(int argc, char *argv[]) {
    unsigned char a = 0x01, b = 0xff;
    unsigned char c = a - b;

    printf("0x%02x 0x%02x 0x%02x\n", a-b, c, minWrap(a,b));

    return EXIT_SUCCESS;
}

Which gave as output:

0xffffff02 0x02 0x02

I would expect the result to be the same three times. My question is: is it always safe to add / subtract unsigned characters and expect them to wrap around 0xff?

Or more general, is it safe to calculate with uintN_tand expect the result to be modulo 2 ^ N?

+4
source share
3 answers

Is it always safe to add / subtract unsigned characters and expect them to wrap at 0xff?

. C char . , char int (), int, else unsigned.

a - b0x01 - 0xFF1 - 255-254.

undefined, %x int, -254 unsigned (. @EOF ). unsigned

printf("0x%02x\n", a-b);
// 0xffffff02

uintN_t , 2 ^ N?

. uintN_t .

#include <inttypes.h>

uint8_t a = 0x01, b = 0xff;
uint8_t diff = a - b;

printf("0x%02x\n", (unsigned) diff);
printf("0x%02" PRTx8 "\n", diff);
+2

a-b printf a b int. , unsigned int - %x .

:

int a1 = a;
int b1 = b;
int x = a1 - b1;
printf("0x%02x 0x%02x 0x%02x\n", x, c, minWrap(a,b));

6.3.1.8 C99 .

int, a unsigned int printf, undefined. , , int unsigned int .

+1

6.3.1.8/1 , :

.

, .

, unsigned integer, .

, , , , .

, , .

.

In this case, the wrapper is well defined. In an expression a-b, since both operands are of type unsigned char, they first advance to int, and the operation is performed. If this value was assigned unsigned char, it would be truncated correctly. However, you pass this value in printfwith the format specifier %xthat is expected unsigned int. To display it correctly, use %hhxthat which expects unsigned char.

+1
source

Source: https://habr.com/ru/post/1607685/


All Articles