Previous: 5 Numeric Data Types and Expression Evaluation
Up: 5 Numeric Data Types and Expression Evaluation
Next: 5.2 New Control Constructs
Previous Page: 5 Numeric Data Types and Expression Evaluation
Next Page: 5.1.1 Signed and Unsigned Integer Types
As we saw in Chapter ,
the range of possible values of objects depends on the sizes used to represent
them. The finite size of an object puts a limit on the range of values that can
be stored in it. Integer objects have a limit on the range of positive and
negative integers. Floating point numbers have limits on the number of
significant digits (known as the precision) as
well as on the range of the exponents (limiting the range of numbers).
We will illustrate the reasons for these limits by analogy
with decimal representation.
Let us represent integers using a finite number of decimal digits, say only five digits are allowed. We can use these digits to represent unsigned positive integers in the range 0 to 99999. If we wish to represent both positive and negative numbers, we need one digit to encode the sign, + or -, and can then use only the remaining four digits to represent the absolute value of an integer. So, with five digits, we can represent positive and negative integers in the range -9999 to +9999. If we had more digits to represent integers, the range of values will be appropriately greater.
Now let us use the same five digits to represent floating point numbers in scientific notation, i.e. a fractional part multiplied by a power of ten. For our discussion, we will assume that the fractional part is less than 1 and that the exponent of ten can be positive or negative. For example:
.234E3 .987E-2 -.345E2The numbers are shown as a fraction times some power of ten where the exponent is shown after the E. The first number is 234.0, the second is .00987, the third is -34.5.
When we represent numbers using this system, we do not need to store the
decimal point (it is always in the same place) or the base (it is
always E, standing for 10). So, of our 5 digits,
let us say that we use three digits for the fractional part and two digits for
the exponent. One digit of the fractional part and one digit of the exponent is
reserved for the sign. This leaves only two digits for the absolute value of
the fractional part, and it leaves one digit for the absolute value of the
exponent. Thus, the range of values for the fractional part
is to
and the range for exponents is
to
.
Even though the range of actual values is quite large
(we can represent numbers from almost negative one billion to positive one
billion), there are only two significant digits of
precision; all other digits will be zeros contributed by the power of ten.
So, the range of numbers is from to
( -.99E+9 to +.99E+9).
With this scheme,
it would be impossible to represent a number such as 123.4567 exactly.
The best we can do is represent it as +.12E+3, which is the number 120 -
not nearly as accurate as 123.4567.
We have a loss of precision (or accuracy) because of the limited number of
digits we have for representing floating point numbers.
There is a slight distinction between precisions and accuracy.
In the above representation scheme, we can always say there are 2 digits
of precision; however, the accuracy depends on the value of the exponent.
The smallest number we can represent is .00000000099 ( +.99E-9),
which is pretty darn accurate.
However, if the exponent is
, our accuracy is only
5 million.
If more digits are used to represent floating point numbers, the
precision and the range can be greater. For example, if 6 digits were allowed,
with four digits for a signed fractional part, we could represent 123.4567 as
+.123E3, which is 123.0.
If 7 digits were allowed, with 5 digits for a signed
fractional part, we could represent the same number as +.1234E3,
which is 123.4, and so forth.
Conceptually, binary representation of numbers is no different from decimal
representation. The finite size imposes a limit on the range of integers and on
the precision and range of floating point numbers. Binary representation is
also tailored to facilitate the basic operations in hardware,
such as addition and
subtraction. For example, as we saw in Chapter ,
integers are typically represented in what is called
the two's complement number system. However, one does not need to know the
number system to realize that the limits on the range of values will be similar
in nature and will depend on the sizes used to represent the numbers.
Recall that, in a computer, memory is organized as a sequence of bytes, each byte with an address, and storage is allocated in units of bytes. For example, if 1 byte is used for signed integers, the range of values (in decimal) is -128 to 127; and unsigned integers have the range 0 to 255. If 2 bytes are used to represent signed integers, the range is -32768 to +32767; and 0 to 65535 for unsigned integers. If 4 bytes are used to represent integers, the range will be appropriately greater. Similarly for floating point numbers; with 4 bytes to represent floating point numbers, the precision is equivalent to about 7 significant decimal digits and a magnitude between approximately 10E38 and 10E-38. If more bytes are used for floating point numbers, the precision and the range are both appropriately greater.
So far we have used char, int, and float data types in our programs. Character data type is usually encoded as an ASCII integer value (signed or unsigned) in one byte of memory. Integers are at least two bytes in size, and floating point numbers are at least four bytes in size. C provides additional integer sizes and floating point data types that provide greater range and/or precision.