CS157: Intro to C, Part II

Spring 2018

Numbers

See this page as a slide show

Bits, Bytes, and Numbers

CS157 Numbers

The Bit

Combinatorics of the Bit

000100
001101
010110
011111

Binary Number System

Binary Number Example

Other Number Systems

BaseNumberIn DecimalIn Binary
Binary11011001081 1 0 1 1 0 0
Octal154       108001 101 100
Decimal108108 
Hexadecimal6C1080110 1100

C Numeric Literals

// assigning the value 10 in different formats
int a = 10, b = 012, c = 0xA;
printf("%d %d %d\n", a, b, c);
10 10 10
// We can print numbers in octal and hex using the
// formatting strings %o and %x, respectively.
printf("%d %o %x\n", 45, 45, 45);
45 55 2d

Representing Integers

Integer Types in C

The full form is short int, but everybody just writes short. It’s like ordering “two salts & a sesame” in a bagel shop.

Integer Types in C

What does the C language itself require?

TypeSize in bytes
char1
short≥ 2
int≥ 2
long≥ 4
long long≥ 8

Integer Types in C

CSU machines, as of August 2016:

TypeBytesMinimum valueMaximum value
short2−32,76832,767
unsigned short2065,535
int4−2,147,483,6482,147,483,647
unsigned404,294,967,295
long8−9,223,372,036,854,775,8089,223,372,036,854,775,807
unsigned long8018,446,744,073,709,551,615
long long8−9,223,372,036,854,775,8089,223,372,036,854,775,807
unsigned long long8018,446,744,073,709,551,615

The signed min & max values are subtly different.

Example

We can use sizeof to see the size of various types on a given machine/compiler. Your sizes may vary!

printf("Size of short int: %zu\n", sizeof(short int));
printf("Size of int:       %zu\n", sizeof(int));
printf("Size of long int:  %zu\n", sizeof(long int));
printf("Size of char:      %zu\n", sizeof(char));
Size of short int: 2
Size of int:       4
Size of long int:  8
Size of char:      1

Overflow

What happens if we try to store a integer number that’s too big for the given type?

short s = 500;
s *= s;
printf("The result: %d\n", s);
The result: -12144
500₁₀=0001 1111 0100
250000₁₀=0011 1101 0000 1001 0000
-12144₁₀=1101 0000 1001 0000

Overflow

Real Numbers

Real Numbers

Rounding Errors and Floating Point Numbers

Floating Point Arithmetic is not Intuitive

float f = 1.0e9;     // one billion
f -= 1.0e9;          // zero
f += 6.0;            // six
printf("f=%f\n", f); // indeed!
f=6.000000
float f = 1.0e9;     // one billion
f += 6.0;            // one billion and six (we hope)
f -= 1.0e9;          // six (we hope)
printf("f=%f\n", f); // but it’s really zero!
f=0.000000

Absorption

Adding small numbers to large numbers may result in absorption.

if (1.0e20 + 1 == 1.0e20)
    puts("equal");
else
    puts("unequal");
equal

Overflow

Attempting to represent numbers that are too large results in overflow.

printf("%e\n", 1.0e306 * 1);
printf("%e\n", 1.0e306 * 10);
printf("%e\n", 1.0e306 * 100);
printf("%e\n", 1.0e306 * 1000);
1.000000e+306
1.000000e+307
1.000000e+308
inf

Underflow

Attempting to represent a number that is too small results in underflow.

printf("%.1e\n", 1.0e-315 / 1.0e0);
printf("%.1e\n", 1.0e-315 / 1.0e3);
printf("%.1e\n", 1.0e-315 / 1.0e6);
printf("%.1e\n", 1.0e-315 / 1.0e9);
1.0e-315
1.0e-318
1.0e-321
0.0e+00

Floating Point Types in C

Example

printf("float: %zu\n",sizeof(float));
printf("double: %zu\n",sizeof(double));
printf("long double: %zu\n",sizeof(long double));
On one machineOn a different machine
float: 4 float: 4
double: 8 double: 8
long double: 12long double: 16

Float versus Double

More printf

Examples

printf("%f\n",   12.3456789);
printf("%.3f\n", 12.3456789);
printf("%.6f\n", 12.3456789);
printf("%e\n",   12.3456789);
printf("%.2e\n", 12.3456789);
12.345679
12.346
12.345679
1.234568e+01
1.23e+01

Same value, different results.

Representation

TypeBitsDigitsBytes
 SignExponentMantissa  
float18247.24
double1115315.98
long double (extended)1156419.212 or 16
long double (quad)11511334.016

Floating-point precision

Limited range

float f = 1.234e37;
printf("f=%g\n", f);
printf("f=%g\n", f*10);
printf("f=%g\n", f*100);
printf("f=%g\n", f*1000);
f=1.234e+37
f=1.234e+38
f=inf
f=inf

Sure, double and long double have greater range, but their ranges are finite.

Limited precision

float f = 1.23456789012345678901234567890;
printf("f=%.25f\n", f);
double d = 1.23456789012345678901234567890;
printf("d=%.25lf\n", d);
long double l = 1.23456789012345678901234567890L;
printf("l=%.25Lf\n", l);
f=1.2345678806304931640625000
d=1.2345678901234566904321355
l=1.2345678901234567889861130
double d = 1.0/49.0;
d *= 49.0;
printf("%.25f\n", d);
0.9999999999999998889776975

Don’t be fooled

Just because it looks precise in decimal doesn’t mean that the floating-point numbers are precise:

double a=0.1, b=0.2;

if (a+b == 0.3)
    puts("Absolutely equal!");
else 
    printf("The difference is %g\n", a+b - 0.3);
The difference is 5.55112e-17

Try this

double a=0.1, b=0.2;
double difference = fabs(a+b - 0.3);
if (difference < 1e-12)
    puts("Close enough for engineering");
else
    puts("Not very close");
Close enough for engineering

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-03-25T16:55

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building