您的位置:首页 > 其它

Chapter 2-02

2015-09-26 00:50 411 查看
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.:

[code]#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

[code]#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:

[code]#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: