Chapter 2-02

来源:互联网 发布:seo软文 编辑:程序博客网 时间:2024/05/16 07:46

Please indicate the source if you want to reprint: http://blog.csdn.net/gaoxiangnumber1
2.2 Integer Representations
2.2.1 Integral Data Types

The C standards define minimum ranges of values that each data type must be able to represent in Figure 2.10:

2.2.2 Unsigned Encodings
Assume we have an integer data type of w bits. We write a bit vector as either x, to denote the entire vector, or as [xw−1, xw−2, … , x0], to denote the individual bits within the vector. Treating x as a number written in binary notation, we obtain the unsigned interpretation of x. We express this interpretation as a function B2Uw (for “binary to unsigned,” length w):

Every unsigned number between 0 and 2w − 1 has a unique encoding as a w-bit value.
2.2.3 Two’s-Complement Encodings
The most common computer representation of signed numbers is known as two’s-complement form. This is defined by interpreting the most significant bit of the word to have negative weight. We express this interpretation as a function B2Tw (for “binary to two’s-complement” length w):

The most significant bit xw−1 is also called the sign bit. Its “weight” is − 2w−1. When the sign bit is set to 1, the represented value is negative, and when set to 0 the value is nonnegative.

Signed number whose binary notation is [xw−1, xw−2, … , x0]:
—TMax:[011…1], 2w-1 - 1
—TMin:[100…0], − 2w−1

For a 32-bit machine, any value consisting of eight hexadecimal digits beginning with one of the digits 8 through f represents a negative number.
2.2.4 Conversions Between Signed and Unsigned
A general rule for C handle conversions between signed and unsigned numbers with the same word size—the numeric values might change, but the bit patterns do not.
2.2.5 Signed vs. Unsigned in C
Most numbers are signed by default, adding character ‘U’ or ‘u’ as a suffix creates an unsigned constant.
When printing numeric values with printf, the directives %d, %u, and %x are used to print a number as a signed decimal, an unsigned decimal, and in hexadecimal format, respectively. Printf does not make use of any type information, and so it is possible to print a value of type int with directive %u and a value of type unsigned with directive %d.
E.g.:

#include<stdio.h>int main(){    int x = -1;    unsigned u = (1 << 32) - 1;    printf("x = %u = %d\n", x, x);    printf("u = %u = %d\n", u, u);    return 0;}

Result:
x = 4294967295 = -1
u = 4294967295 = -1
When an operation is performed where one operand is signed and the other is unsigned, C implicitly casts the signed argument to unsigned and performs the operations assuming the numbers are nonnegative.
2.2.6 Expanding the Bit Representation of a Number
Convert an unsigned number to a larger data type: add leading zeros to the representation.
Convert a two’s-complement number to a larger data type: adding copies of the most significant bit to the representation. [xw−1, xw−2 , … , x0] -> [xw−1 , … , xw−1, xw−1, xw−2 , … , x0 ].

Conversion from one data size to another and between unsigned and signed

#include<stdio.h>int main(){    short sx = -12345;    unsigned uy = sx;    printf("First conversion:%u\n", uy);    unsigned short temp = sx;    uy = temp;    printf("Second conversion:%u", uy);    return 0;}

Result:
First conversion:4294954951
Second conversion:53191
By default, the compiler first convert data size, then convert between signed and unsigned (First conversion); we can change order as Second conversion. They have different results.
2.2.7 Truncating Numbers
When truncating a w-bit number x = [xw−1, xw−2, … , x0] to a k-bit number, we drop the high-order w − k bits, giving a bit vector x = [xk−1 , xk−2 , … , x0].
For an unsigned number x, the result of truncating it to k bits is equivalent to computing x mod 2k.
For a two’s-complement number x, x mod 2k can be represented by an unsigned number having bit-level representation [xk−1, xk−2 , … , x0 ], but we treat the truncated number as being signed, i.e.: U2Tk (x mod 2k).

2.2.8 Advice on Signed vs. Unsigned
2.3 Integer Arithmetic
2.3.1 Unsigned Addition
Unsigned addition is equivalent to computing the sum modulo 2w (assume total w bits), i.e.: discarding the high-order bit in the w+1-bit representation of x + y.
E.g.: consider a 4-bit number representation with x = 9([1001]) and y = 12([1100]). Their sum is 21, having a 5-bit representation [10101]. But if we discard the high-order bit, we get [0101] decimal value 5. This matches the value 21 mod 16 = 5.
s = x + y;(0 <= x, y <= 2w - 1, 0 <= s <= 2w+1 - 2) overflow has occurred if and only if s < x (or equivalently, s < y).
Proof:
—When s doesn’t overflow: s =(x + y) ≥ x;
—When s does overflow, s = x + y − 2w(the value of w+1-bit). Because y < 2w, so y − 2w < 0, hence s = x + (y − 2w ) < x.
/* return 1: not overflow; 0: overflow */
int uadd_ok(unsigned x, unsigned y)
{
unsigned sum = x+y;
return sum >= x;
}

if x < 0 && y < 0, but x + y >= 0: negative overflow;
if x > 0 && y > 0, but x + y < 0: positive overflow.
Test program:

#include<stdio.h>int main(){    int a = 1 << 31;  // the min value    int b = 0x80000000;  // same as 1 << 31    printf("negative overflow test: %d\n", a + b);    a = 0x7fffffff;  // the max value    b = a;    printf("positive overflow test: %d\n", a + b);    return 0;}

Result:
negative overflow test: 0
positive overflow test: -2
2.3.3 Two’s-Complement Negation

Ways to calculate two’s-complement negation:
1. -x = ~x + 1.
2. Split the bit vector into two parts. Let k be the position of the rightmost 1: [xw−1, xw−2 , … , xk+1, 1, 0, … 0]. Negation: [~xw−1, ~xw−2 , … ~ xk+1, 1, 0, … , 0].
Please indicate the source if you want to reprint: http://blog.csdn.net/gaoxiangnumber1

0 0
原创粉丝点击