2.3 Integer Arithmetic 2.31 unsigned addition
The addition of unsigned numbers, in general there are rules: for the two W-bit unsigned number x, y Add, if x + y < 2w (including this value above this value is the W-bit unsigned number can not be represented), then their worth x + y, if x + y beyond this range, then caused the overflow , the value of x + y is equal to X + y-2w (actually x + y mod 2w, which can only overflow to w bit for addition, so here are the two equivalents) ... After overflow there is a very obvious feature is that the result is less than two of the number of any one ... It is also easy to prove that:
For overflow there is: s = x + y-2w, because X, Y is obviously less than 2w, then S = x + (y-2w) or S = y + (x-2w), obviously y plus a negative number of course less than y ... So judging whether an overflow can be written like this:
1 int UADD_OK (unsigned x, unsigned y) {2 return x + y >=
3//The reason not to write x + y >= x && x + y >= y is because the result of X + y is either greater than or equal to X, Y is either less than X and less than y ... 6?
2.32 complement addition
There are rules for complement addition:
I think this is also very well understood, when the result of two complement X, Y adds more than the w-1 bit can represent the range, then the natural value needs to be represented by the W bit, but for the signed number of the first w bit is as a sign bit, its weight is exactly a negative value, so that the calculated result is not in line with the normal law, The same can be understood negative overflow ... Sum up so judging whether an overflow can be written like this:
int TADD_OK (intint y) { return000 000))}
A summary is this: the unsigned number overflow will be positive or 0, but no matter what gets, will be less than two addend; Signed number overflow only two cases, one is to get a number greater than or equal to 0, at this time the two number must be negative, the other is to get less than 0 of the number, at this time the two numbers must be positive. 2.3.3 complement of non-
This I feel is actually very simple, but the most feeling of translation into the complement of the non-a bit awkward (because it is in the C language ~ that is, the negation of the bitwise operation is not really related, but also in the logical operation of the!), here is not to ask for the opposite number (is to add equals 0 number), In addition to the -2w-1 all the other values are directly take negative operation, and for this number is itself, that is, in the case of W position, the range of the lower value (the minimum value) is not itself, the other directly take negative.
Two ways to complement each other, I am personally accustomed to the second, faster and more error-prone ...
1. Direct ~x + 1 for X non-essential
2. The bit before the first 1 from the LSB including the 1 will remain the same, after all the reverse can be ...
2.34 unsigned multiplication
Unsigned multiplication is not really the same as addition, it is very simple, theoretically the two unsigned number of W-bit will need to be 2w for the representation, but in fact, because only W-bit to represent the result, then the result can only be this:
2.35 complement multiplication
In terms of bit-level notation, complement multiplication and unsigned multiplication are consistent, and the advantage is that the machine can use the same set of instructions for the multiplication of signed and unsigned numbers-that is, in this process of calculation (that is, the difference lies in the interpretation, in fact the bit-level representation is identical):
So how do we prove that the instruction used to count unsigned numbers also conforms to the mathematical rules when dealing with signed (complement) numbers? In other words, the shape of 1 * 2 = 2 Using this method of calculation should also be the correct answer, and we found that x, Y (with the apostrophe) after the multiplication in accordance with the complement is the same as the complement is the same, this is the correct way to explain.
2.35 proof is very simple not to write, 2.36 my first answer is as follows (note my answer is the wrong answer):
1 int Tmult_ok (int x, int y) { 2 long long p = (long long ) x * 3 p = p >> 32 ; 4 return p = = 0 | | p = =-1 5 }
The reference answer is direct 3, 4 line changed to return p = = (int) p, at first I think the effect should be the same, otherwise, for example, high 32 bits are 1, low 32 bits in the highest bit is 0 of the case, my function to judge the result is no overflow, actually has overflowed. So the reference to the answer is right.
The 2.37 question is actually the malloc function parameter, the topic itself as the background story to understand, not much meaning ...
2.36 Times constant
In most machines, the integer multiplication instruction is quite slow (requires 10 or more clock cycles, addition subtraction bit level, and shift operation requires only 1 clock cycles), so the compiler tries to replace multiplication with shift and addition, which is an important optimization method. For example, the optimization of X * 14 to (x << 3) + (x << 2) + (x << 1) or (x << 4)-(x << 1), this Part I personally think is not particularly important, just need to know There is such an optimization within the Tao machine and the compiler.
2.37 divided by the power of 2
In addition to the Fabienne multiplication is slower (requires 30 or more cycles), integer division has a feature that is rounded to 0, we look at the number of unsigned, for example, 4-bit machine number, 1101 (13) Right to move 1 bits (divided by 2), the result is 0110 (6), is consistent ... But for the signed number, it is in the positive range is also consistent, but in the negative range but not in accordance with, such as just in this example 1101 (-3) Right to move 1 bits (divided by 2), the result is 1110 (-2) instead of the expected -1 ...
This is the proof of the equivalence of unsigned digit shift and division:
In fact, this formula is also applicable to the complement, but why the complement is negative when the problem? The problem is that part of the abandoned X two, that part is abandoned (that is, 0), for positive numbers, the smaller the closer to 0, but for negative numbers, the larger the closer to 0, so the original part is 1, is closer to 0, and now 0, so the problem ... The problem is that the shift operation is actually a floor division and for the complement negative, what he needs is Ceil division, so the solution is how to convert x/Y (< 0, y > 0) to the equivalent shift operation ... This piece of the book Speaks very well:
But division and multiplication are a bit different here, unlike multiplication, not any x/k (k is constant) can be implemented using shift operations. A piece I think is also know such a thing, on the line, but this exercise feel is quite good, go with do ... 2.42:
int div16 (int x) { returnto4;}
2.3.8 on the final thinking of integer arithmetic
The integer operation performed by the computer is actually a form of modulo operation, which indicates that the finite word length of a number limits the range of possible worthwhile values, and the result may overflow. While the complement is quite magical, it provides a way to represent positive negative numbers, while still using the same bit-level implementation as the unsigned number. At the same time to pay attention to the unsigned, he is conceptually simple, but there will always be some unexpected results ...
2.44:
A: error when x = = 0X80000000, x-1 > 0 (overflow occurred)
B: Yes
C: Error (May overflow)
D: For
E: Error, when x = 0X80000000,-x = = < 0
F: Yes
G: Yes (first UX * Uy in-place representation is X * y, while ~y =-y-1)
Representation and processing of information (3)