简体   繁体   中英

Does C uses 2's complement internally to evaluate unsigned numbers arithmetic like 5-4?

I have C code as

#include<stdio.h>

int main()
{
    unsigned int a = 5;
    unsigned int b = 4;
    printf("%u",a-b);
}

Output of above code is 1, I am thinking that C has calculated internally the result as taking 2's compliment of -4 and then using compliment arithmetic to evaluate the result. Please correct me if anything I am interpreting wrong. (Here, I am talking about how C actually calculates result using binary)

Does C uses 2's complement internally to evaluate unsigned numbers arithmetic like 5-4?

No, for two reasons.

unsigned int a = 5, b = 4;
printf("%u",a-b);

C guarantees that arithmetic on unsigned integer types is performed modulo the size of the type. So if you computed ba , you'd get -1 which would wrap around to UINT_MAX , which is probably either 65535 or 4294967295 on your machine. But if you compute ab , that's just an ordinary subtraction that doesn't overflow or underflow in any way, so the result is an uncomplicated 1 without worrying about 2's complement or modulo arithmetic or anything.

If your compiler, or your CPU architecture, chooses to implement a - b as a + -b , that's their choice, but it's an implementation detail way beneath the visibility of the C Standard, or ordinary programmers like you and me, and it won't affect the observable results of a C program at all.

Where things get interesting, of course, is with addition and subtraction of signed quantities. Up above I said that under unsigned arithmetic, 4 - 5 is -1 which wraps around to UINT_MAX . Using signed arithmetic, of course, 4 - 5 is -1 which is -1. Under 2's complement arithmetic, it Just So Happens that the bit patterns for -1 and UINT_MAX are identical (typically 0xffff or 0xffffffff ), and this is why 2's complement arithmetic is popular, because your processor gets to define, and your C compiler gets to use, just one set of add and sub instructions, that work equally well for doing signed and unsigned arithmetic. But (today, at least), C does not mandate 2's complement arithmetic, and that's the other reason why the answer to your original question is "no".


But to be clear (and to go back to your question): Just about any C compiler, for just about any architecture, is going to implement a - b by emitting some kind of a sub instruction. Whether the processor then chooses to implement sub as a two's complement negate-and-add, or some other kind of negate-and-add, or via dedicated bitwise subtraction-with-borrow logic, is entirely up to that processor, and it doesn't matter (and is probably invisible) as long as it always returns a mathematically appropriate result.

The arithmetic method generally whatever is most natural on the target hardware. It is not defined by the C language.

When a processor's ALU has at least int sized registers, ab will not doubt be implemented as a single SUB instruction (or whatever the target's op-code mnemonic for subtraction might be). In the hardware logic it may well be that the logic is equivalent to a + (~b + 1) (ie 2's complement the RHS and add) - but that is a hardware logic/micro-code implementation issue, not a language or compiler behaviour.

At Godbolt for GCC x86 64-bit, the statement:

 unsigned int c = a - b ;

generates the following assembly code (my comments):

    mov     eax, DWORD PTR [rbp-4]      ; Load a to EAX
    sub     eax, DWORD PTR [rbp-8]      ; Subtract b from EAX
    mov     DWORD PTR [rbp-12], eax     ; Write result to c

So in that sense your question is not valid - C does not do anything in particular, the processor performs the subtraction intrinsically.

The C standard allows 2's, 1's and sign+magnitude arithmetic, but in practice the world has settled on 2's complement and machines that use other representations are arcane antiques that probably never had C compilers targeted for them in any case.

There are in any case moves to remove the option for anything other than 2's complement in the language: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2218.htm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM