Computer Science 15-100, Fall 2008
Class Notes:  More Data and Expressions


  1. Data Conversion
    1. Assignment Conversion
    2. Method Invocation Conversion
    3. Promotion
    4. Casting
  2. Primitive Data Types
    1. 8 Types and Their Ranges
    2. Narrowing / Widening chart
  3. Arithmetic Operators Widen Operands To At Least 32 Bits
  4. Overflow
  5. Underflow
  6. Assignment operators
    1. Examples
    2. Compound Assignment Operators Can Be Narrowing
  7. Pre- and post- increment and decrement operators
  8. String.split
  9. Scanner.useDelimiter
  10. format and printf
    1. Simple use
    2. Equivalence of "printf" and "format"
    3. Use of String.format
    4. The Conversion Types
    5. format and printf Examples
    6. Field width
    7. Flags:  Left-Justified ('-'), Use-Sign ('+'), and Zero-Padded ('0')
    8. Precision
  11. StringBuffer

More Data and Expressions

  1. Data Conversion
     
    1. Assignment Conversion
      class MyCode {
        public static void main(String[] args) {
           int a = 5;
           double b = a; // Assignment conversion
           System.out.println("a = " + a); // 5
           System.out.println("b = " + b); // 5.0
        }
      }
    2. Method Invocation Conversion
      class MyCode {
        public static void main(String[] args) {
           int a = 4;
           double b = Math.sqrt(a); // Method invocation conversion
           System.out.println("a = " + a); // 4
           System.out.println("b = " + b); // 2.0
        }
      }

      Another Example:

      class MyCode {
        public static void main(String[] args) {
           short s1 = 1;
           short s2 = 2;
      
           // The next line demonstrates method invocation
           // conversion (converting the shorts to ints).
           int imax = Math.max(s1,s2);
           System.out.println(imax);
      
           // The next line demonstrates BOTH method invocation
           // conversion (converting the shorts to ints) AND
           // assignment conversion (converting the int to a double)
           double dmax = Math.max(s1,s2);
           System.out.println(dmax);
        }
      }
    3. Promotion
      class MyCode {
        public static void main(String[] args) {
           int a = 5;
           double b = (2.0 + a); // Promotion
           System.out.println("a = " + a); // 5
           System.out.println("b = " + b); // 7.0
        }
      }
    4. Casting
      class MyCode {
        public static void main(String[] args) {
           double a = 5.0;
           int b    = (int) a; // Casting
           System.out.println("a = " + a); // 5.0
           System.out.println("b = " + b); // 5
        }
      }
  2. Primitive Data Types
     
    1. 8 Types and Their Ranges
       

      Type

      Description

      Size Min Max
      long Integers between -9 billion billion and
      +9 billion billion.
      That is, signed 64-bit integers.
      8 bytes
      (64 bits)
      Long.MIN_VALUE
      =-263
      = -9223372036854775808
      = about -9 billion billion
      Long.MAX_VALUE
      = 263 - 1
      = 9223372036854775807
      = about +9 billion billion
      int Integers between -2 billion and +2 billion.
      That is, signed 32-bit integers.
      4 bytes
      (32 bits)
      Integer.MIN_VALUE
      = -231 = -2147483648
      (about -2 billion)
      Integer.MAX_VALUE
      = 231-1 = 2147483647
      (about +2 billion)
      char Characters (like 'A' or 'z' or '&')
      (Technically:  the integer Unicode values representing characters, with values between 0 and +65535.)
      That is, unsigned 16-bit integers.
      2 bytes
      (16 bits)
      Character.MIN_VALUE
      = 0
      Character.MAX_VALUE
      = 216-1 = +65535
      (about 65 thousand)
      short Integers between -32768 and +32767
      That is, signed 16-bit integers.
      2 bytes
      (16 bits)
      Short.MIN_VALUE
      = -215 = -32768
      Short.MAX_VALUE
      = 215-1 = +32767
      byte Integers between -128 and +127
      That is, signed 8-bit integers.
      1 byte
      (8 bits)
      Byte.MIN_VALUE
      = -27 = -128
      Byte.MAX_VALUE
      = 27-1 = +127
      double Floating-point numbers with a huge range. 8 bytes
      (64 bits)
      -Double.MAX_VALUE
      = -1.7976931348623157E308
      (about -1.8 x 10308).

      Also, smallest positive is:
      Double.MIN_VALUE
      = 4.9E-324
      (about 5 x 10-324)
      Double.MAX_VALUE
      = 1.7976931348623157E308
      (about +1.8 x 10308).

      Also, negative closest to zero is:
      -Double.MIN_VALUE
      = -4.9E-324
      (about -5 x 10-324)
      float Floating-point numbers, like doubles, only with less accuracy 4 bytes
      (32 bits)
      -Float.MAX_VALUE
      = -3.4028235E38
      (about -3.4 x 1038).

      Also, smallest positive is:
      Float.MIN_VALUE
      = 1.4E-45
      (about 1.4 x 10-45)
      Float.MAX_VALUE
      = 3.4028235E38
      (about +3.4 x 1038).

      Also, negative closest to zero is:
      -Float.MIN_VALUE
      = -1.4E-45
      (about -1.4 x 10-45)
      boolean true or false values 1 byte
      (8 bits)
      n/a n/a

      Example:

      class MyCode {
        public static void main(String[] args) {
          // Demonstrate the different integer primitive data types
          long  xlMax = Long.MAX_VALUE;
          int   xiMax = Integer.MAX_VALUE;
          short xsMax = Short.MAX_VALUE;
          char  xcMax = Character.MAX_VALUE;
          byte  xbMax = Byte.MAX_VALUE;
      
          long  xlMin = Long.MIN_VALUE;
          int   xiMin = Integer.MIN_VALUE;
          short xsMin = Short.MIN_VALUE;
          char  xcMin = Character.MIN_VALUE;
          byte  xbMin = Byte.MIN_VALUE;
      
          // Note:  you do not yet need to know about "format" (soon...)
          System.out.format("%5s %25s %25s\n","type","max","min");
          System.out.format("%5s %25d %25d\n","long", xlMax,xlMin);
          System.out.format("%5s %25d %25d\n","int",  xiMax,xiMin);
          System.out.format("%5s %25d %25d\n","short",xsMax,xsMin);
          System.out.format("%5s %25d %25d\n","char", (int)xcMax, (int)xcMin);
          System.out.format("%5s %25d %25d\n","byte", xbMax,xbMin);
      
          // Demonstrate the different floating-point primitive data types
          float  xfMax = Float.MAX_VALUE;
          double xdMax = Double.MAX_VALUE;
      
          float  xfMin = Float.MIN_VALUE;  // Not what you may expect!!!
          double xdMin = Double.MIN_VALUE;
      
          // Note:  you do not yet need to know about "format" (soon...)
          System.out.println();
          System.out.printf("%5s %25s %25s\n","type","max","min");
          System.out.printf("%5s %25g %25g\n","float",  xfMax,xfMin);
          System.out.printf("%5s %25g %25g\n","double", xdMax,xdMin);
        }
      }
    2. Narrowing / Widening chart
       
      value
      (bits)
      double
      (64)
      float
      (32)
      long
      (64)
      int
      (32)
      short
      (16)
      byte
      (8)
      char
      (16)
      -1.8 x 10308              
      -3.4 x 1038              
       about -9 billion billion              
      about -2 billion              
      -32768              
      -128              
      0              
      +127              
      +32767              
      +65535              
      about +2 billion              
      about +9 billion billion              
      +3.4 x 1038              
      +1.8 x 10308              

      Example:

      class MyCode {
        public static void main(String[] args) {
          // From the chart, we see that shorts are wider than bytes,
          // so we can convert from byte-to-short without casting.
          byte b = 99;
          short s = b;
          System.out.println("s = " + s);
      
          // Conversely, because bytes are narrower than shorts,
          // we must cast to convert from short-to-byte.
          s = 42;
          b = (byte) s;
          System.out.println("b = " + b);
        }
      }

      Another Example:

      class MyCode {
        public static void main(String[] args) {
          // From the chart, we see that shorts are wider than chars,
          // AND chars are wider than shorts!!!
          // So we must cast in EITHER direction!
          char c = 'A';
          short s = c;  // will not compile without a cast!
          System.out.println("s = " + s);
      
          s = 4;
          c = s;        // ALSO will not compile without a cast!
          System.out.println("c = " + c);
        }
      }
  3. Arithmetic Operators Widen Operands To At Least 32 Bits
    class MyCode {
      public static void main(String[] args) {
        // Works for "int", "long", "double", and "float"
        int i1 = 1;
        int i2 = 2;
        int i3 = i1 + i2;
    
        // Fails for "char", "short", and "byte"
        char c1 = 1;
        char c2 = 2;
        char c3 = c1 + c2;  // Will not compile without a cast!
      }
    }
  4. Overflow
    class MyCode {
      public static void main(String[] args) {
        // 1. We know the range of byte is [-128,+127], so we
        //    know that adding 100+100 will overflow.
        byte b1 = 100;
        byte b2 = 100;
        byte b3 = (byte) (b1 + b2);
        System.out.println(b3 < 0); // true, due to overflow
    
        // 2. But what is the EXACT value of b3?  For this, we
        //    do the addition ourselves in 8-bit 2's complement:
        //    100 = 64 + 32 + 4 --> 0110 0100
        //    So:   100  =  0110 0100
        //         +100   + 0110 0100
        //                  ---------
        //                  1100 1000
        //    As the sign bit is 1, this is negative, so we overflowed.
        //    To what value?  Just negate this number (by flipping bits
        //    and adding one):
        //                  0011 0111 (flipped bits)
        //                 +0000 0001 (plus one)
        //                  ---------
        //                  0011 1000 (= 32 + 16 + 8 = 56)
    
        //    Since our negated answer is 56, our original answer is -56.
        System.out.println(b3); // -56, as predicted!
      }
    }
  5. Underflow
    class MyCode {
      public static void main(String[] args) {
        double d = Double.MIN_VALUE;
        System.out.println(d); // prints 4.9E-324
        System.out.println((d / 2.0) == 0.0);  // underflow!
      }
    }
  6. Assignment operators
    1. Examples

      import java.util.Scanner;
      class MyCode {
        public static void main(String[] args) {
          int sentinel = -1;
          System.out.println("Enter numbers (" + sentinel + ") to end:");
          Scanner scanner = new Scanner(System.in);
          int x, sum, sumOfSquares;

          sum = sumOfSquares = 0;  // Uses assignment as an operator!

          while ((x = scanner.nextInt()) != sentinel) {  // ditto!
            sum += x;
            sumOfSquares += x*x;
          }

          System.out.println("Sum of values = " + sum);
          System.out.println("Sum of squares = " + sumOfSquares);
        }
      }


      A Confusing Example:

      class MyCode {
        public static void main(String[] args) {
          int w = 1;
          int x = 2 * (w += 3);  // Maybe ok, but contrived...
          System.out.println(w + "," + x);

          int y = 1;
          int z = y + (y += 4) + (y += 5); // Very bad idea!
          System.out.println(y + "," + z);
        }
      }

       
    2. Compound Assignment Operators Can Be Narrowing
      class MyCode {
        public static void main(String[] args) {
          int i;
          double d;
      
          // Assignment operators can be narrowing!!!
          i = 1;
          d = 2.5;
          i += d;
          System.out.println(i);
      
          // This works without casting because the above code
          // is identical to this:
          i = 1;
          d = 2.5;
          i = (int)(i + d);
          System.out.println(i);
      
        }
      }
  7. Pre- and post- increment and decrement operators
    class MyCode {
      public static void main(String[] args) {
        int x = 5, y = 0;
        System.out.println(x + "," + y);
        y = x++;
        System.out.println(x + "," + y);
        y = ++x;
        System.out.println(x + "," + y);
        y = 10 + x--;
        System.out.println(x + "," + y);
        y = 10 + --x;
        System.out.println(x + "," + y);
      }
    }

    A Realistic Example:

    import java.util.Arrays;
    class MyCode {
      // Returns an array containing all the elements in a and b
      public static int[] concat(int[] a, int[] b) {
        if (a == null) return b;
        if (b == null) return a;
        int[] c = new int[a.length + b.length];
        int i = 0;
        for (int j=0; j<a.length; j++)
          c[i++] = a[j];
        for (int j=0; j<b.length; j++)
          c[i++] = b[j];
        return c;
      }
    
      public static void main(String[] args) {
        int[] a = { 1, 2, 3};
        int[] b = { 4, 5 };
        int[] c = concat(a, b);
        System.out.println(Arrays.toString(c));
      }
    }

    And A Very Confusing Example:

    class MyCode {
      public static void main(String[] args) {
        int x = 1;
        x += x++;  // Never do this!!!
        System.out.println(x);
      }
    }
  8. String.split
    class MyCode {
      public static void main(String[] args) {
        // Demonstrates some simple uses of s.split().
        // For more details on how to specify delimiters, see:
        // http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html
    
        // Create an array using spaces as delimiters
        String s = "one two three four five six";
        String[] a = s.split(" "); // use spaces as delimiters
        printArray(a, "Using spaces as delimiters");
    
        // Now using commas as delimiters
        s = "one, two, three, four, five, six";
        a = s.split(","); // use commas as delimiters
        printArray(a, "Using commas as delimiters");
    
        // Now using comma-followed-by-space as delimiters
        s = "one, two, three, four, five, six";
        a = s.split(", "); // commas-followed-by-spaces
        printArray(a, "Using comma-followed-by-space as delimiters");
    
        // Now using EITHER commas OR spaces as delimiters
        s = "one, two, three, four, five, six";
        a = s.split("[, ]"); // either commas or spaces
        printArray(a, "Using either commas or spaces as delimiters");
    
        // Try to use dots (periods) as delimiters
        s = "a.b.c.d";
        a = s.split(".");  // does not work right!
        printArray(a, "Failed attempt to use dots (periods) as delimiters");
    
        // Fixed version using dots (periods) as delimiters
        s = "a.b.c.d";
        a = s.split("\\.");  // dots (periods!)
        printArray(a, "Using dots (periods) as delimi\ters");
      }
    
      // Helper method to print array a with some more details than Arrays.toString()
      private static void printArray(String[] a, String msg) {
        System.out.println(msg);
        System.out.println("a.length = " + a.length);
        for (int i=0; i<a.length; i++)
          System.out.println("a[" + i + "] = \"" + a[i] + "\"");
        System.out.println("------------------");
      }
    }
  9. Scanner.useDelimiter

    Simple Example:
    import java.util.*;
    class MyCode {
      public static void main(String[] args) {
        Scanner scanner = new Scanner("800-555-1212");
        scanner.useDelimiter("-");
        while (scanner.hasNext())
          System.out.println(scanner.next());
      }
    }

    Another Example (Showing similarity to String.split):

    import java.util.*;
    class MyCode {
      public static void main(String[] args) {
        // Demonstrates some simple uses of Scanner.useDelimiter().
        // For more details on how to specify delimiters, see:
        // http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html
    
        // Create a scanner using spaces as delimiters
        String s = "one two three four five six";
        Scanner scanner = new Scanner(s);
        scanner.useDelimiter(" ");  // use spaces as delimiters
        printScannerValues(scanner, "Using spaces as delimiter");
    
        // Now using commas as delimiters
        s = "one, two, three, four, five, six";
        scanner = new Scanner(s);
        scanner.useDelimiter(","); // use commas as delimiters
        printScannerValues(scanner, "Using commas as delimiters");
    
        // Now using comma-followed-by-space as delimiters
        s = "one, two, three, four, five, six";
        scanner = new Scanner(s);
        scanner.useDelimiter(", "); // commas-followed-by-spaces
        printScannerValues(scanner, "Using comma-followed-by-space as delimiters");
    
        // Now using EITHER commas OR spaces as delimiters
        s = "one, two, three, four, five, six";
        scanner = new Scanner(s);
        scanner.useDelimiter("[, ]"); // either commas or spaces
        printScannerValues(scanner, "Using either commas or spaces as delimiters");
    
        // Try to use dots (periods) as delimiters
        s = "a.b.c.d";
        scanner = new Scanner(s);
        scanner.useDelimiter(".");  // does not work right!
        printScannerValues(scanner, "Failed attempt to use dots (periods) as delimiters");
    
        // Fixed version using dots (periods) as delimiters
        s = "a.b.c.d";
        scanner = new Scanner(s);
        scanner.useDelimiter("\\.");  // dots (periods!)
        printScannerValues(scanner, "Using dots (periods) as delimiters");
      }
    
      // Helper method to Scanner values in a manner similar to printArray
      // from the previous example.
      private static void printScannerValues(Scanner scanner, String msg) {
        System.out.println(msg);
        int i = 0;
        while (scanner.hasNext()) {
          String next = scanner.next();
          System.out.println("Scanned string #" + i + " = \"" + next + "\"");
          i++;
        }
        System.out.println("Total strings scanned:  " + i);
        System.out.println("------------------");
      }
    }
  10. format and printf
     
    1. Simple use

         int x = 3;
         double d = 4.5;
         System.out.printf("x = %d\n",x); // %d prints an integer
         System.out.printf("d = %f\n",d); // %f prints a floating point number
       
    2. Equivalence of "printf" and "format"

         int x = 3;
         double d = 4.5;
         System.out.format("x = %d\n",x);
         System.out.format("d = %f\n",d);

       
    3. Use of String.format

         int x = 3;
         double d = 4.5;
         String s;
         s = String.format("x = %d\n",x);
         System.out.print(s);
         s = String.format("d = %f\n",d);
         System.out.print(s);
       
    4. The Conversion Types

      %[flags][width][.precision]conversion

      b boolean
      d decimal integer
      o octal integer
      h hex integer
      H Hex integer
      f Floating-point number
      e Floating-point number in scientific notation
      g Floating-point number in compact form
      s String

       

    5. format and printf Examples

         // convert to hexadecimal
         int y = 165;
         System.out.printf("%d\n",y); // 165
         System.out.printf("%h\n",y); // a5
         System.out.printf("%H\n",y); // A5

         // different forms of floating-point numbers
         double d = Math.pow(Math.PI,20);
         System.out.printf("%e\n",d); // 8.769957e+09
         System.out.printf("%f\n",d); // 8769956796.082693
         System.out.printf("%g\n",d); // 8.76996e+09
       
    6. Field width

         int y = 123, z = 45;
         System.out.printf("123456789\n");  // 123456789
         System.out.printf("%4d%4d\n",y,z); //  123  45
         System.out.printf("%1d%4d\n",y,z); // 123  45
       
    7. Flags:  Left-Justified ('-'), Use-Sign ('+'), and Zero-Padded ('0')

         int y = 123, z = 45;
         System.out.printf("123456789\n");    // 123456789
         System.out.printf("%4d%+4d\n",y,z);  //  123 +45
         System.out.printf("%-4d%+4d\n",y,z); // 123  +45
         System.out.printf("%+05d%4d\n",y,z); // +0123  45
       
    8. Precision

         double d = 45.678;
         System.out.printf("%.0f\n",d);    // 46
         System.out.printf("%.1f\n",d);    // 45.7
         System.out.printf("%.2f\n",d);    // 45.68
         System.out.printf("%+06.2f\n",d); // +45.68
         System.out.printf("%+07.2f\n",d); // +045.68

       
  11. StringBuffer

    A Simple Example:

    import java.util.*;
    class MyCode {
      public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("abc");
        sb.append("\n");
        sb.append("def");
        String s = sb.toString();
        System.out.println(s);
      }
    }

    A Realistic Example:

        // Adapted from java/util/Arrays.java
        public static String toString(int[] a) {
            if (a == null)
                return "null";
            if (a.length == 0)
                return "[]";
     
            StringBuffer buf = new StringBuffer();
            buf.append('[');
            buf.append(a[0]);
     
            for (int i = 1; i < a.length; i++) {
                buf.append(", ");
                buf.append(a[i]);
            }
     
            buf.append("]");
            return buf.toString();
        }

    And The Kicker:

    import java.util.*;
    class MyCode {
      public static void main(String[] args) {
        System.out.println("Demonstrate relative speeds of");
        System.out.println("String.concat and StringBuffer.");
        System.out.println();
        int n = 10000;
    
        System.out.println("Timing with 'small' n = " + n + ":");
        testStringConcatenation(n);
        testStringBuffer(n);
        System.out.println();
    
        n = 1000000;
        System.out.println("Timing with 'large' n = " + n + ":");
        // testStringConcatenation(n); // would take too long!
        testStringBuffer(n);
        System.out.println();
      }
    
      public static void testStringConcatenation(int n) {
        System.out.print("Timing String concatenation with n=" + n + ":  ");
        String s = "";
        long time0 = System.currentTimeMillis();
        for (int i=0; i<n; i++)
          s = s + "abc";
        long time1 = System.currentTimeMillis();
        System.out.println((time1 - time0) + " ms");
      }
    
      public static void testStringBuffer(int n) {
        System.out.print("Timing StringBuffer with n=" + n + ":  ");
        StringBuffer buff = new StringBuffer();
        long time0 = System.currentTimeMillis();
        for (int i=0; i<n; i++)
          buff.append("abc");
        String s1 = buff.toString();
        long time1 = System.currentTimeMillis();
        System.out.println((time1 - time0) + " ms");
      }
    }

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem