Computer Science Building, Princeton University


Introduction to CS


1.  A Simple Machine

2.  Java Programming

    • Hello World

    • Primitive Types

    • Conditionals, Loops

    • Input and Output

    • Arrays

    • Functions

    • Recursion

3.  OOP

4.  Data Structures

5.  A Computing Machine

6.  Building a Computer

7.  Theory of Computation

8.  Systems

9.  Scientific Computation

10.  Perspective


 Lecture Notes

Assignments

FAQ









2.2. PRIMITIVE DATA TYPES


A data type is a set of values and a set of operations defined on them. For example, we are familiar with numbers and with operations defined on them such as addition and multiplication (in mathematics, we are accustomed to thinking of the set of numbers as being infinite; in computer programs we have to work with a finite number of possibilities).

There are eight different built-in types of data in Java, mostly different kinds of numbers. Other types are available in system libraries, and programming in Java is actually centered around building our own data types, as we shall see later. We use the system type for strings of characters so frequently that we also consider it here.

Basic definitions. We use the following four statement Java program fragment to introduce some terminology that we'll be using:

int a, b, c;
a = 1234;
b = 99;
c = a + b;

The first statement declares three variables with the identifiers a, b, and c to be of type int. The next two assignment statements change the values of the variables, using the literals 1234 and 99. The final statement assigns c to have the value 1333 by evaluating the expression a + b.

Characters and Strings. A char is an alphanumeric character or symbol, like the ones that you type. We usually do not perform any operations on characters other than assigning values to variables. A String is a sequence of characters. The most common operation that we perform on strings is known as concatenation: given two strings, chain them together to make a new string. For example, consider the following Java program fragment:

String a, b, c;
a = "Hello,";
b = " Bob";
c = a + b;

The first statement declares three variables to be of type String. The next three statements assign values to them, with the end result that c has the value "Hello, Bob". Using string concatenation, Program Ruler.java prints the relative lengths of the subdivisions on a ruler.

Integers. An int is an integer (whole number) between -231 and 231 - 1   (-2,147,483,648 to 2,147,483,647). We use ints frequently not just because they occur frequently in the real world, but also they naturally arise when expressing algorithms. Standard arithmetic operators for addition, multiplication, and division, for ints are built in to Java, as illustrated in IntOps.java. The user enters the two integer parameters on the command line by typing

java IntOps 1234 99

We use the built-in Java method Integer.parseInt to convert string values to integer values. Assuming the user enters 1234 and 99 as the two values, the following two statements will set a to 1234 and b to 99.

int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);

The type long is similar to int except it can represent integers in a much larger ranger, between -263 an 263 - 1. We occasionally use long when we need to work with huge integers.

Real numbers. The double type is for representing floating-point numbers, e.g., for use in scientific applications. The internal representation is like scientific notation, so that we can compute with real numbers in a huge range. We can specify a floating point number using either a string of digits with a decimal point, e.g., 3.14159 for a 6 six digit approximation to π , or with a notation like scientific notation, e.g., 6.022E23 for Avagadro's constant 6.022 × 1023. Quadratic.java shows the use of doubles in computing the two roots of a quadratic equation using the quadratic formula. The Java Math library defines trigonometric functions, logarithm/exponential, and other common functions for doubles. DoubleOps.java illustrates their use.

Booleans. The boolean type has just two values: true or false. The apparent simplicity is deceiving - booleans lie at the foundation of computer science. The most important operators defined for booleans are for and, or, and not.

Although these definitions are intuitive and easy to understand, it is worthwhile to fully specify each possibility for each operation in a truth table.

a b a && b a || b
false false false false
false true false true
true false false true
true true true true

Comparisons. The comparison operators are mixed-type operations that take operands of one type (e.g., int or double) and produce a result of type boolean. These operations play a critical role in the process of developing more sophisticated programs.

op meaning a op b true false
!= not equal !(a == b) 3 != 2 2 != 2
less than a is less than b 2 <13 2 <2
<= less than or equal (a 2 <= 2 3 <= 2
> greater than !(a <= b) 13 > 2 2 > 13
>= greater than or equal !(a 3 >= 2 2 >= 3

LeapYear.java tests whether an integer corresponds to a leap year in the Gregorian calendar using Boolean and comparison operations. Every fourth leap year is a leap year except for century years that are not divisible by 400. In other words, a year is a leap year if it is divisible by 4 (2004) unless it is divisible by 100 in which case it is not (1900), unless it is divisible by 400 in which case it is (2000). Here's is Stanley Rabinowitz's entertaining response to a question as to why OpenVMS assumes that 2000 is a leap year.

Type conversion. We often find ourselves converting data from one type to another. Our programs use several different techniques to convert between different types of data. This type conversion applet among 20 different basic Java types.

Explicit type conversion. We can convert from one type to another by calling a method that takes an argument of one type and returns a result of another type. For example, the library method Math.round takes a double argument and return a long result which is the nearest integer to the argument. Thus, for example Math.round(3.14159) and Math.round(2.71828) are both of type long and have the same value (3). We frequently use the methods Integer.parseInt and Double.parseDouble to convert from strings to integers and doubles, respectively.

Automatic type conversion. For primitive numeric types, the system automatically performs type conversion when we use a value whose type has a larger range of values than expected. For example, if we wrote the quadratic formula program to take integer command line parameters, as in IntQuadratic.java, then, Java would perform a number of automatic type conversions. It would convert b*b - 4*c to be of type double before calling the method Math.sqrt since this is the type that Math.sqrt expects. Additionally, when computing -b + discriminant, the value b would be converted from an int to a double before being added to discriminant, since the latter variable is of type double. The system does this type of conversion automatically because your intent is clear and it can do so with no loss of information. On the other hand, if the conversion might involve loss of information, for example, if you try to assign a double to an int, you will get an error message from the compiler.

Explicit casts. Java also has some built-in type conversion methods for primitive types that you can use when you are aware that you might lose information, but you have to make your intention using something called a cast. For example the expression (int) 3.14159 is a cast from a value of type double that results in the value 3 of type int. This type of cast converts from a real number to an integer by discarding the fractional part and rounding towards zero. Program RandomInteger.java reads in a parameter N and prints out a "random" integer between 0 and N-1. The program uses Math.random to generate a "random" real number between 0.0 and 1.0. We produce an integer in the desired range by multiplying the real number by N and discarding the fractional part.

Automatic conversions for strings. The built-in type String obeys special rules. One of these special rules is that you can easily convert any type of data to a String. Java invokes the appropriate method automatically whenever we use the + operator when one of its operands is a String. For example, the result of the code fragment

String a = "";
int b = 99;
String c = a + b;

is that c has the value "99". We use this automatic conversion liberally in our programs.

Q + A

Q. How do I get the | symbol on my keyboard?

A. It's there. Often it's above the \ symbol.

Q. How do I know when to use whitespace?

A. You get whitespace when you use the space, tab, or return key. We often use it for purely cosmetic reasons to make the program more readable for the programmer (and grader). It is good style to separate each operator (+, *, &&) with a space on either side. Sometimes, you must not use whitespace, e.g., in between the two characters of the <= operator or adjacent to a period, as in System.out.println. With practice you will remember when you need whitespace and when you don't. For now, if in doubt, try to mimic our style.

Q. Java prints out a ton of digits when I System.out.print a double. How can I format it so it displays only 3 digits after the decimal place?

A. We won't worry about formatting at this point since it involves more complicated concepts. If you're curious, check our FAQ.

Q. Why does the integer quotient -0/3 yield 0, but the double quotient -0.0/3.0 yields -0.0?

A. Java represent integers using something called two's complement notation, and there is only one representation of 0. (You'll learn about this in Section 5.1.) Java represents doubles using IEEE specifications, and there are two distinct representations of the number zero, 0 and -0. (You'll learn about this in Section 9.1.)

Q. What happens when I use / and % with a negative numerator?

A. Try it and see. -47 / 5 = -9 and -47 % 5 = -2. The quotient is always rounded toward zero. To ensure the identity b * (a / b) + (a % b) = a, this means that the result of the remainder operator can be negative. This convention was inherited from ancestral languages like FORTRAN and C. Some languages (but not Java) include both remainder and modulo operators because it is often convenient to have % return only nonnegative integers.

Q. Can I use % with real numbers?

A. Yes. If x is nonnegative, then x % (2 * Math.PI) is the real number between 0 and 2 π that results after subtracting off multiples of 2 π.

Q. How do I print a "?

A. Since " is a special character when dealing with strings, you must escape the convention rules by using \". For example, System.out.println("She said \"Oh\" afterwards");.

Q. OK, so then how do I print a \?

A. Use "\\".

Q. Are there any restrictions on the variable names I can use?

A. Yes. A Java identifier is a Java letter, followed by an unlimited sequence of Java letters and Java digits. Java letters can be drawn from the entire Unicode character set, although we will restrict attention to English characters. The underscore and dollar sign are also considered Java letters. By convention, variables usually begin with a lowercase letter. An identifier cannot be named any of the following reserved words.

 abstract    default    goto          package      this
 assert      do         if            private      throw
 boolean     double     implement     protected    throws
 break       else       import        public       transient
 byte       *enum       instanceof    return       true
 case        extends    int           short        try
 catch       false      interface     static       void
 char        final      long          strictfp     volatile
 class       finally    native        super        while
 const       float      new           switch
 continue    for        null          synchronized

* beginning in Java 1.5

Lessons

Exercises

  1. What does the following sequence of statements do?
    t = x;
    x = y;
    y = t;
    
  2. Write a program TrigIdentity that uses Math.sin and Math.cos to check that sin2θ + cos2θ = 1 for any θ. Your program should take in one real-valued command line argument θ and print out sin2θ + cos2θ.
  3. Show that the expression (!(a && b) && (a || b)) || ((a && b) || !(a || b)) is equivalent to true.
  4. Simplify the following expression: (!(a b))
  5. The exclusive or function for boolean variables is defined to be true if they are different and false if they are the same. Give a truth table for this function.
  6. Explain how to use Program Quadratic.java to compute the square root of a number.
  7. What do each of the following print?
    1. System.out.println(2 + "bc"); prints: 2bc
    2. System.out.println(2 + 3 + "bc"); prints: 5bc
    3. System.out.println((2+3) + "bc"); prints: 5bc
    4. System.out.println("bc" + (2+3)); prints: bc5
    5. System.out.println("bc" + 2 + 3); prints: bc23
  8. What do each of the following print?
    1. System.out.println('b');
    2. System.out.println('b' + 'c');
    3. System.out.println((char) ('a' + 4));
  9. Suppose that a variable a is declared as int a = 2147483647. What do each of the following print? Explain each outcome.
    1. System.out.println(a);
    2. System.out.println(a + 1);
    3. System.out.println(2 - a);
    4. System.out.println(-2 - a);
    5. System.out.println(2 * a);
    6. System.out.println(4 * a);
  10. Suppose that a variable a is declared as double a = 3.14159. What do each of the following print? Explain each outcome.
    1. System.out.println(a);
    2. System.out.println(a + 1);
    3. System.out.println(8 / (int) a);
    4. System.out.println((int) 8 / a);
    5. System.out.println(8 / a);
    6. System.out.println((int) (8 / a);
  11. Describe what happens in Quadratic.java if you write sqrt instead of Math.sqrt.
  12. What is the value of (Math.sqrt(2) * Math.sqrt(2) == 2)?
  13. Can you find values a, b, and c such that Math.sqrt(b*b - a*c) is invalid (NaN) but (b*b

    Creative Exercises

    1. Uniform random numbers. Write a program that uses Math.random to print ten uniform random values between 0.0 and 1.0 and then prints their average value. Here, uniform means that the value is equally likely to be any number between 0.0 and 1.0.
    2. Wind chill. Given the temperature T (in Fahrenheit) and the wind speed V (in miles per hour), the National Weather Service defines the effective temperature (the wind chill) to be:
      W = 35.74 + 0.6215 T + (0.4275 T - 35.75) V0.16
      Write a program WindChill.java that takes two integer command-line arguments T and V and prints out the wind chill. Hint: use Math.pow(a, b) to compute ab.
    3. Car loan payments. Write a program CarLoan.java that reads in three command line parameters P, Y, and R and calculates the monthly payments you would have to make over Y years to pay off a P dollar loan at R per cent interest compounded monthly. The formula is
                       P r
      payment =  ---------------,  where n = 12 * Y, r = R / 120
                 1  - (1 + r)^(-n)
      

      % java CarLoan
      Caveat: in Chapter 9, we will consider more accurate ways to compute this quantity, so before you go off to run an online bank, be sure to learn about roundoff error.
    4. Polar coordinates. Write a program Polar.java that converts from Cartesian to polar coordinates. Your program should take two real numbers x and y that are between 0 and 1 on the command line and print the corresponding polar coordinates r and θ. Use the Java methods Math.sqrt and Math.atan2. Note that Math.atan2 takes two input x and y and returns the arc tangent of y/x between -π and π (in radians). It's well-defined even if x is zero.
    5. Day of the week. Write a program Day.java to read in a date and tell you what day of the week that date falls on. Your program should take three command line arguments, M (month), D (day), and Y (year). For M use 1 for January, 2 for February, and so forth. For output print 0 for Sunday, 1 for Monday, and so forth. Use the following formulas for the Gregorian calendar:
      y = Y - (14 - M) / 12
      x = Y + Y/4 - Y/100 + Y/400
      m = M + 12 * ((14 - M) / 12) - 2
      d = (D + x + (31*m)/12) mod 7
      
      
      Example: On what day of the week was August 2, 1953?
      
      y = 1953 - 0 = 1953
      x = 1953 + 1953/4 - 1953/100 + 1953/400 = 2426
      m = 8 + 12*0 - 2 = 6
      d = (2 + 2426 + (31*6) / 12) mod 7 = 2443 mod 7 = 0
      
      Answer: Sunday.
      
    6. Dragon curve. Write a program Dragon.java to print the instructions for drawing the dragon curves of orders 1 through 6. The instructions are strings of the characters 'F', 'L', and 'R', where F means "draw a line 1 unit straight ahead", L means "turn left", and R means turn right. A dragon curve of order n is formed when you fold a strip of paper in half n times, then unfold to right angles. The key to drawing one is to note that a curve of order n is a curve of order n-1 followed by an L followed by a curve of order n-1 traversed in reverse order and that the same instructions, except with the middle L changed to an R, traverse the curve in reverse order.

    Web Exercises

    1. What does the following code fragment print out?
      double x = (double) (3/5);
      System.out.println(x);
      

      0.0 since the integer division is done before the cast.

    2. Why doesn't the following program print out 4294967296 = 2^32?
      int x = 65536;
      long y = x * x;
      System.out.println(y);
      
      The product of the two int values is computed as an int, and then automatically converted to a long. But 65536 * 65536 = 2^32 overflows a 32 bit int before it gets converted.
    3. Fibonacci word. Write a program FibonacciWord.java that prints the Fibonacci word of order 0 through 10. f(0) = "a", f(1) = "b", f(2) = "ba", f(3) = "bab", f(4) = "babba", and in general f(n) = f(n-1) followed by f(n-2). Use string concatenation.
    4. Simulating a standard Gaussian random variable. One way to simulate a standard Gaussian random variable is via the Box-Muller formula
      Z = sin(2 π V) (-2 ln U)1/2
      where U and V and real numbers between 0 and 1 generated by the Math.random method. Write a program StdGaussian.java that prints out a standard Gaussian random variable. Note that Math.log is the base e logarithm - this is what mathematicians traditionally designate with ln.
    5. Simulating a Gaussian random variable. Write a program Gaussian.java that takes two command line parameters μ and σ and print out a Gaussian deviate with mean μ and standard deviation σ. If Z is a standard Gaussian random variable, then σ Z + μ is a Gaussian random variable with mean μ and standard deviation σ.
    6. Standard deviation. Modify Exercise 13 so that it prints out the sample standard deviation in addition to the average.
    7. Great circle. Write a program GreatCircle.java that reads in four parameters L1, G1, L2, and G2 (the latitude and longitude of two points on the earth) and prints out the great circle distance in miles between them.
      d = 69.1105 * arccos(sin(L1)*sin(L2) + cos(L1)*cos(L2)*cos(G1-G2))
      (Do we need to round G1-G2 to be between 0 and 180 for shortest distance?) All angles are in degrees. However, the trigometric functions in Java are in radians. Use Math.toRadians and Math.toDegrees to convert back and forth. Use Math.abs to compute the absolute value.

      Example 1: Paris: 48.87° N, -2.33° W. Austin: 30.27° N, 97.74° W.
      Example 2: Leningrad: 59.9° N, -30.3° W. San Francisco: 37.8° N, 122.4° W.

      Great Circle
    8. Write a program that reads in three parameters and prints true if all three are equal, and false otherwise.
    9. What happens if you compile LeapYear.java and execute it with
      1. java LeapYear
      2. java LeapYear 1975.5
      3. java LeapYear -1975
      4. java LeapYear 1975 1976 1977
    10. What does the compiler do if you try to write the following expression:
      int a = 27 * "three";
      
    11. What does the compiler do if you try to write the following expression:
      double x;
      System.out.println(x);
      

      Answer: it complains that the variable x might not have been initialized. Variables within main are not automatically initialized.

    12. Fun with comments. What is the value of a after the following code fragment is executed?
      //*/
      a = 17;
      /*/
      a = -17;
      //*/
      
      Repeat the question after deleting the first /.
    13. What does the following code fragment print.
      int threeInt = 3;
      int fourInt  = 4;
      double threeDouble = 3.0;
      double fourDouble  = 4.0;
      System.out.println(threeInt / fourInt);
      System.out.println(threeInt / fourDouble);
      System.out.println(threeDouble / fourInt);
      System.out.println(threeDouble / fourDouble);
      
    14. What does the following statement do where grade is a variable of type int?
      if (97 <= grade <=100) system.out.println("a+); else system.out.println("try harder"); 

      Answer: syntax error since <= is a binary operator. You must rewrite it as (97 <= grade && grade <=100).

    15. Write a program that takes four real-valued command line parameters x1, y1, x2, and y2 and prints the Euclidean distance between the points (x1, y1) and (x2, y2). Use Math.sqrt.
    16. Write a program Ascending.java that reads in three integer command line parameters x, y, and z. Create a boolean variable b that is true if the three values are in ascending order (x ≤ y ≤ z), and false otherwise. Print out the variable b. Caveat: it is not legal in Java to chain two comparison operators together as in (x <= y <=z).

    17. Write a program Ordered.java that reads in three integer command line arguments, x, y, and z. Create a boolean variable b that is true if the three values are either in ascending or in descending order, and false otherwise. Print out the variable b.
    18. Write a program Divisibility.java that reads in two command line inputs and prints true if both are divisible by 7, and false otherwise.
    19. Area of a triangle. Write a program TriangleArea.java that takes three command line inputs a, b, and c, representing the side lengths of a triangle, and prints out the area of the triangle using Heron's formula: area = sqrt(s(s-a)(s-b)(s-c)), where s = (a + b + c) / 2.
    20. RGB to CMYK color matching. There are a number of different formats for storing colors. The RGB format specifies the level of red (R), green (G), and blue (B) on an integer scale of 0 to 255. This format is commonly used in television screens, computer monitors, digital cameras, and web pages. (The primary color yellow is used instead of green because yellow phosphors are much more expensive to produce.) CMYK format specifies the level of cyan (C), magenta (M), yellow (Y), and black (K) on a real scale of 0.0 to 1.0. This model is widely used for color photographs and offset printing in magazines. Write a program RGBtoCMYK.java that reads in three integers R, G, and B from the command line and prints out the equivalent CMYK parameters. To calculate, let C' = 1 - R / 255, M' = 1 - G / 255, Y' = 1 - B / 255, K = min(C', M', Y'), C = C' - K, M = M' - K, Y = Y' - K. Hint: use Math.min(x, y) to get the minimum of two values and Math.min(Math.min(x, y), z) to get the minimum of three values.
    21. CMYK to RGB color matching. Write a program CMYKtoRGB that reads in four command line inputs C, M, Y, and K between 0 and 1, and prints out the corresponding RGB parameters. Devise the appropriate formula by "inverting" the RGB to CMYK conversion formula.
    22. Temperature conversion. What is wrong with the following code fragment to convert from Fahrenheit (F) to Celsius (C)?
      double C = (F - 32) * (5 / 9);
      
    23. Exponentiation. What is wrong with the following code fragment to compute a2, where a is of type double?
      double b = a^2;
      

      Answer: in Java, ^ does not mean exponentiation (it's the exclusive or function from logic). Use a*a instead. To compute ax, use Math.pow(a, x). Note that Math.pow returns a double so that you would need an explicit cast if a and b in the above example were integers.

    24. What of the following statements is legal?
      boolean b = 1;
      boolean b = true;
      boolean b = "true";
      boolean b = True;
      

      Answer: only the second one.