Types of Data / More Bits
Subtitles of the Movie
Modern computers all use two's complement notation for binary integer values. In the past some machines used one's complement. The arithmetic is slightly simpler with one's complement in most cases. But one's complement has both a positive and negative zero so it can get complicated. Two's complement has only one representation for each number so it's easier to work with in the long run. As you know, with a binary integer, the first bit is the signed bit. If it is one, the number is negative. If it is zero, the number is positive. You can reverse the sign of a number by changing all the one bits to zero and all the zeros to one and then adding one. This example starts off with an integer set to the value of 852. The tilde operator is the one's complement operator. It changes all the one bits to zero and all the zero bits to one. Then one is added. The process is repeated then. A one's complement and then adding one and the value comes right back to where it started. Here's what happens when you run it. You can see that taking the one's complement of a positive number results in a negative number that's off by one. But adding one results in the correct negative value. To switch the sign the other way, the same procedure is followed. Take the one's complement, which results in a value off by one and then adding one to it brings it back to the original number. This dual operation of complement and add is what happens internally when you use a minus sign to negate a number. Take a look at this operation. Here the two integers, A and B, are used with the exclusive or operator. First A is exclusive or with B, then B exclusive or with A, then A is exclusive or with B again. The values of the two integers are displayed both before and after this operation. Here's what happens when you run it. Values of A and B are swapped. It's the only way I know of to swap the contents of two variables without using an intermediate storage location. When you shift bits in an integer, you need to know what's going to happen. When shifting to the left, the left-most bits are lost and zero bits are introduced on the right whether or not the number is unsigned. However, the way those numbers are interpreted is a bit different. These two integer values, one signed and one unsigned, are both shifted to the left by two positions. That should double the number twice; multiply it by four. But remember, bits on the left are being lost. The bit pattern of the two numbers is the same but you can see that the negative number was multiplied by four as expected but the unsigned number simply reduced its value. That's because it was already at its maximum possible value so any change will reduce it. In this case, zeros were introduced in it's lowest value bits so it was reduced by three; the ones bit and the twos bit. Shifting to the right has a different effect. The shift operator acts differently for signed and unsigned numbers. The right-most bit is lost for both signed and unsigned but for a signed number the left-most bit is duplicated to fill the new vacancy. For an unsigned number, a zero is inserted. The result is that this time the negative valued doesn't change while the unsigned value is divided by four. None of this is mysterious but you need to understand how the shift operators work so you won't be surprised by their actions. You can define your own special sizes for integers. You do that by defining inside a struct an int or an unsigned int followed by a colon and the number of bits it is to contain. This is most often done to match the layout you read from a file or from a device where the data items are packed into odd numbers of bits. In this example you can see integers defined for the lengths of one, three, two and six. Notice the integer length of six doesn't have a name. You can do this to insert fillers and line the data items up. All the declarations must be an int or an unsigned int except the special case of the Boolean types. Notice that the first integer in the struct, the one named X doesn't have a length specified for it. It's a standard int and whatever is the default size for this compiler. Once you have defined your integers, you can work with them the same as you would with any integer. In expressions, the smaller defined ints are converted to regular ints for calculation and the ints are automatically trimmed to the size before they're stored back into memory. Notice the last statement in this example. In the struct is a 32-bit integer followed by a total of 13 bits of special sized integers with the overall size as eight bytes. The first four bytes are the 32-bit integer and the other integers take up a total of 32 bits. The compiler pads out the rest of the struct so it's not necessary for you to fill out the struct to define the bits that you're not going to use. This is not something you'll use very often but when you do need it, this approach is certainly nicer than masking and shifting to get and set smaller bit fields.
Tutorial Information
| Course: | Advanced C Programming |
| Author: | Arthur Griffith |
| SKU: | 33965 |
| ISBN: | 1-935320-24-6 |
| Release Date: | 2009-01-30 |
| Duration: | 5.5 hrs / 82 lessons |
| Work Files: |
Yes |
| Captions: | Available on CD and Online University |
| Compatibility: |
Vista/XP/2000, OS X, Linux QuickTime 7, Flash 8 |
VTC Sign up & Benefits
- Unlimited Access
- 81,350 Video Tutorials (20,800 free)
- Video Available as Flash or QuickTime
- Over 782 Courses
- $30 for One Month Access
- Multi-User Discounts Available
United States 