CSC 115.005/006 Sonoma State University Spring 2022
Scribbler 2
CSC 115.005/006:
Programming I
Scribbler 2
Instructor: Henry M. Walker

Lecturer, Sonoma State University
Professor Emeritus of Computer Science and Mathematics, Grinnell College


Course Home References Course Details: Syllabus, Schedule, Deadlines, Topic organization MyroC Documentation Project Scope/
Acknowledgments

Notes:

Data Representation of Numbers in C: Unit Overview

Through this point in the course, programs have consistently used int variables to store integer values (numbers without decimal points), and double variables to store floating point values (numbers with decimal points). For the most part, these two types have worked well, and we have not worried about how the numbers were stored behind the scenes.

However, the C programming language provides several types for integers and several more for floating point numbers. The 2011 C Standard even provides for data types involving complex numbers. With so many choices, it is reasonable to ask "Why?" — "Why several types of integers, floating point numbers, and complex numbers?" Further, one might ask, "why have separate types of numbers (e.g., int and double) — why not just one type of number for all applications?"

As with many topics within computer science, the underlying answer to such questions relates to finding a balance between storage space and accuracy. For example, some int types require rather little storage, but also can store only a small range of values or provide limited precision. Similarly, versions of int type are very helpful for some applications, whereas versions of double are needed in other applications.

The following examples may highlight some of the underlying issues discussed later in this unit.


Example 1: Adding 0.1 Iteratively from 0.0 to 1.0

Consider the problem of starting at 0.0 and adding 0.1 repeatedly until reaching 1.0. As a safety measure, we add a counter, so the loop continues no more than 20 iterations. A simple C program follows.


/*  Example 1:  Adding 0.1 Iteratively from 0.0 to 1.0 
    Used in Data Representation Overview
*/

#include <stdio.h>

int main ()
{
  int i = 0;
  double sum = 0.0;
  double increment = 0.1;
  
  /* print column header */
  printf ("  i            sum\n");

  /* print iterations */
  while ((sum != 1.0) && (i < 20))
    {
      printf ("%3d %20.17lf\n", i, sum);
      i++;
      sum += increment;
    }

  /* print concluding result */
  printf ("loop concluded with i=%d, sum=%lf\n", i, sum);
  return 0;
}

The expected output likely is 0.0, 0.1, 0.2, 0.3, ..., 0.9, with a concluding with loop concluded with i=10, sum=1.0.

Try Example 1 in JavaScript several times, with increments 0.1, 0.2, 0.25, and 0.50.

Example 1 in JavaScript

For Web pages, we use JavaScript for sample program runs. JavaScript uses the equivalent of C's double type for all numbers (i.e., no int). In the following examples, results for JavaScript are identical to those for C!

Enter an increment, as in C program, and click "Run Example 1".

Increment:        




Example 2: Successive Multiplication by 2

Suppose we want to compute powers of 2, and also add 1 or two to those powers. Start output at a designated power of 2 and continue until a designated last power. A simple C program follows.


As with Example 1, we use JavaScript for sample program runs. Once again, results for JavaScript are identical to those for C.

Enter an increment, as in C program, and click "run Example 2".

Start power:     End power:    




/*  Example 2:  Successive Multiplication by 2
    Used in Data Representation Overview
*/

#include <stdio.h>

int main ()
{
  int start_power = 0;
  int end_power = 56;
  double power2 = 1;
  int i;

  /* compute  2^start_power to begin */
  for (i = 1; i ≤ start_power; i++)
    {
      power2 *= 2;
    }
  
  /* print column header */
  printf ("  i            power=2^i              ");
  printf ("power+1              power+2\n");

  /* print iterations */
  for ( ; i ≤ end_power; i++)
    {
      printf ("%3d %20.0lf %20.0lf %20.0lf\n",
                i, power2, power2+1, power2+2);
      power2 *= 2;
    }

  return 0;
}

Much of the output from this program may be as expected, but values with exponent 54 and above may be surprising.

Try Example 2 with JavaScript. Since output can be long, feel free to run the program with several starting and ending values for the powers of 2 (or use the defaults to view a long listing).

As with Example 1, this unit on numeric representation will provide insight on where and why Example 2 produces unexpected results. Also, the discussion in this unit will illustrate circumstances one must take into account when writing programs!

Note: This code assumes 0 <= start power <= end power <= 67

To compute and print 2start, 2start+1, 2start+2, ..., 2end,


One Additional Observation

Look one more time at the values of 254, 254+1, and 254+2 from Example 2. Using the results from Example 2,

This example shows that the associative property (from mathematics) (a + b) + c need not be the same as a + (b + c) when using floating point numbers. Additional exciting results follow through this unit!