So, for the case (where f(x, y) = 1, x = 1010, and y = 0001) I've filled it out like so:
f(x, y) = 1 | x = 1010 | y = 001
zx = 1 | x = 0000 |
nx = 1 | x = 1111 |
zy = 1 | | y = 0000
ny = 1 | | y = 1111
x + y = 1111 + 1111 = 1110
So, now I have to negate the result.
I understand the example where we negate 4 and then the little exercise where we convert 6 to -6, but I'm experiencing a bit of brain lock here.
The decimal form of 1110 is 14. To negate this, do I just subtract 16 (2^4) - 14 to get 2 (0010)?
Be careful about what you mean by "negate" -- it's meaning depends on the context in which it is used.
If you are talking about the ALU's operations, then "negate" means to flip each bit. This is a hardware operation and the hardware doesn't care about what the bit pattern represents, it simply does a bit-wise Not of the pattern.
So the nz=1 results in 1110 becoming 0001, which is what you want.
What you are trying to do is "negate" in terms of taking the "arithmetic additive inverse" -- or having the effect of multiplying a value by -1. This DOES depend on how we interpret the pattern as a whole as a value. if you are allowing negative numbers (using 2's complement representation, which is the only one Nand-2-Tetris discusses, but there are others), then 1110 is NOT 14 in decimal, but rather -2.
With 2's complement, you can always negate a number (i.e., take it's additive inverse) by subtracting it's n-bit representation from 2^n (using unsigned arithmetic). It doesn't matter whether the number is positive or negative. But this is NOT what the ALU is doing internally -- the only item within the ALU that does anything with the bit pattern as a whole is the adder (and the output flags zr and ng if we want to be precise).