Read Chapter 2
Section 2.1: Information Storage
- Modern computers store information in 8-bit bytes
- A bit can hold one of 2 values: 0 or 1
- 8 bits can hold 2*2*2*2*2*2*2*2 = 28 values
- A byte can contain an integer between 0 and 255
- A single byte can represent:
- an integer between 0 and 255
- an integer between -128 and 127
- a character (at most 256 possibilities)
- something else: examples
Storage Examples
- Two consecutive bytes can represent:
- an integer between 0 and 65535 = 216 - 1
- an integer between -32768 and 32767
- a unicode character
- a floating point number
- a character string of length 1
- something else: examples
- 4 consecutive bytes can represent:
- an integer between 0 and 4,294,967,295 = 232 - 1
- an integer between -2,147,483,648 and 2,147,483,647
- a floating point number
- a character string of length at most 3.
- an array of 4 bytes
- something else: examples
- Data types in C and their sizes (in bytes):
- char: 1
- short: 2 (almost always)
- int: usually 4
- long: usually 4 also, may be 8
- long long: usually 8
- char *: usually 4 or 8
- float: almost always 4
- double: almost always 8
Today's News: January 15
No recitations this week
- Computer arithmetic does not always follow the usual rules of mathematics:
Example:
Suppose we have:
int x,y,z;
and assume that an int is represented as 4 bytes.
Because an int is signed, its maximum value is 2
31 - 1.
What is the output by the following?
x = 2000000000; /* 2 billion */
y = x;
z = x + y;
printf("%d %d %d\n",x,y,z);
Answer: 2000000000 2000000000 -294967296
What is the relationship between 4,000,000,000 and 294,967,296?
Relation From Addition
Section 2.1.1
Sections 2.1.2 - 2.1.4
The
word size of a computer is the largest number of bytes
the computer can handle efficiently.
This somewhat vague definition will be clarified in Chapter 3.
Typical word sizes are 4 bytes (32-bit machine) and 8 bytes (64-bit machine).
The early microprocessors were 8-bit (1 byte) word machines.
What does the following program do?
#include <stdio.h>
int main() {
int x = 1;
printf("%d at %p\n",x,&x);
return 0;
}
If an int takes up 4 bytes, what is stored in each of
the bytes of this int?
What does the following program do?
#include <stdio.h>
int main() {
int x = 1;
int i;
char *p = (char *)&x;
for (i=0;i<sizeof(int);i++)
printf("%d ",p[i]);
printf("\n");
return 0;
}
little endian: low order byte of multi-byte
integers are stored first (smallest address).
Examples of little endian machines:
Intel x86
big endian: high order byte of multi-byte
integers are stored first (smallest address).
Examples of big endian machines:
PowerPC
Sparc (usually)
Why does it matter whether you are using a little endian
or big endian machine?
Usually it doesn't - except when it does.
Endian Matters
Section 2.1.5
A character is usually represented as a single byte by using the ASCII code.
Properties of the ASCII code:
- Codes for digits are consecutive: '0'=48, '1'=49, etc.
- Codes for upper case letters are consecutive: 'A'=65, 'B'=66, etc.
- Codes for lower case letters are consecutive: 'a'=97, 'b'=98, etc.
- Note that lower case letters come after upper case letters:
relevant for sorting
- Maximum value is 127.
ASCII Order
Strings are represented as arrays of characters terminated by the
null character.
The
null character is a single byte with value 0.
Section 2.1.6
Programs are stored in memory as a sequence of bytes.
The representation depends on the the hardware of the machine and is
described in Chapter 3.
Section 2.1.7 - 2.1.8
You should be familiar with the logical operators for
AND, OR and NOT when applied to Boolean values (true or false).
A single bit can represent a Boolean value: 0=false, 1=true.
We can then apply logical operators to bits or collections of bits.
We use the following symbols:
&: and
|: or
~: not
^: exclusive or (true if one is true but not both)
Some examples:
Bit Operations
In C we can apply these operators to any integral data type such as
char, short, int, long, etc.
Section 2.1.9
Logical Operations in C are similar to the bitwise operations, but they
act upon the entire data item with
0 still representing false but
any other value is true.
The result of a logical operator in C has the value 0 or 1.
See the examples in Section 2.1.9
Section 2.1.10
Shift Operations in C:
Left shift: x << y shifts x left y bits.
Right shift: x >> y shifts x right y bits.
- Shifts should only be performed on unsigned
values or signed values that are known to be nonnegative.
- Vacated positions are filled with 0.
- The amount of shift should be smaller than the size
of the item shifted (in bits).
- The result of a left shift is equivalent to multiplying by 2y
if no overflow (1 bits shifted out) occurs.
- The result of a right shift is equivalent x/2y.
- If you do not follow the rules, the results are not defined
(anything can happen).
- Many C compilers perform arithmetic right shifts on negative values in which
the vacated values are filled with the sign bit.
- Java has the >>> operator to perform arithmetic right shifts.
Back to CS 3843 Notes Table of Contents