Fundamental C - Expressions |
Written by Harry Fairhead | ||||||||
Tuesday, 24 May 2022 | ||||||||
Page 4 of 4
The rules, known as the usual arithmetic conversions seem complicated. The C99 standard says:
The most worrying part of this specification is point 3 as converting a signed integer to an unsigned of the same rank seems to invalidate the arithmetic. You have to remember that two’s-complement arithmetic works even if you consider the value to be unsigned. For example: unsigned int myUnsigned=1; int myInt=-1; myInt=myInt+myUnsigned; printf("%d \n",myInt); In this case the signed int is converted to unsigned and it looks as though we are going to get the answer 2 as the negative is lost. This is not how it works. The signed int is converted to an unsigned int with the same bit pattern. When added together the roll over occurs and the result is the same in two's-complement. That is, it prints 0 and we have the correct answer. This doesn’t mean that you cannot get the wrong answer. For example: unsigned int myUnsigned=UINT_MAX; int myInt=1; myInt=myInt+myUnsigned; printf("%d \n",myInt); In this case you will still see zero printed, which in this case is probably the wrong answer. Again we have the same bit patterns. The UINT_MAX is -1 when regarded as a signed int and hence the final result is zero. To get the correct answer we need to explicitly use a cast to long long: unsigned int myUnsigned=UINT_MAX; int myInt=1; long long mylong= (long long)myInt+(long long)myUnsigned; printf("%lld \n",mylong); In fact, we don’t need to cast myInt to long long because the rules will promote it to the same as myUnsigned.
Notice that these casts are only performed in expressions, including comparison operators, and bitwise operators. They are not performed for assignment operators. In most cases the result of expressions involving mixed types give you the correct answer but if in doubt use explicit casts. A common idiom, however, is to rely on the rules to change integer arithmetic into floating-point arithmetic. For example: int myInt=1; float ans=myInt/100; gives the answer 0 as integer division is performed before the result is converted to a float. However: int myInt=1; float ans=myInt/100.0; gives the result 0.01 as the literal is now a float and hence myInt is automatically converted to a float. In chapter but not in this extract
Summary
Related ArticlesRemote C/C++ Development With NetBeans Getting Started With C/C++ On The Micro:bit Fundamental C: Getting Closer To The MachineNow available as a paperback and ebook from Amazon.
Also see the companion volume: Applying C <ASIN:1871962609> <ASIN:1871962463> <ASIN:1871962617> <ASIN:1871962455>
To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info
|
||||||||
Last Updated ( Tuesday, 24 May 2022 ) |