# Working with Primitive Types

## Type Attributes, Strong Type Checking

### Working with Primitive Types

• What we will see:
• Ada has a richer type model than Java
• Ada has strong type checking than Java
• with a few exceptions

• Sample types: Numeric, other primitive types, enumerated types
• Operators
• Literals
• Numeric output
• Keyword and default parameters
• Type Attributes
• Strong type checking
• Implicit and explicit conversions
• Type checking and I/O

• Find the average of 3 integers (wow!)
• Illustrates some numeric types:

• Things to note:
• Declaration section of program
• Numeric types `Integer` and `Float`
• Declarations are written as variable: Type

• Assignment is `:=` (= is equals)

• Explicit coercion (ie type cast): use type as function

• Attributes: 'image and 'img operate like tostring (see below)

### Primitive Types

• Integer, Long_Integer
• Float

• Boolean: values are `true` and `false`

• Character (8 bit)
• Wide_Character (16 bit)
• Wide_Wide_Character (32 bit)

• String:
• Strings are arrays of characters
• Strings are fixed length
• 3 kinds of strings are available
• More detail later

### Operator Precedence and Associativity

• Levels of precedence:
• ```        Highest         **   abs  not
Multiplying     *    /    rem  mod
Relational      =    /=   <    >  <= > =
Logical         and  or   xor
```
• Associativity: left to right for operators at same level

### Arithmetic Operators

• Basic Arithmetic: `+, -, *, /`
• Each operates on two integers or two floats
• Division of two integers truncates the result
• Example: -7 / 2 = -3

• Absolute value: abs (Example: x := abs y;)

• Remainder and Modulus: ` mod, rem`
• Same for positive operands
• rem
• Same as java %
• Absolute value of result always the same
• Sign of result is sign of left operand
• Example: (-2) rem 12 = -2
• Equation (a/b)b + (a rem b) = a is true when a/b truncates toward 0

• mod
• Good for clock arithmetic
• Example: (1 - 3) mod 12 = 10
• Sign of result is sign of right operand
• Equation (a/b)b + (a mod b) = a is true when a/b truncates toward -∞

• Power: ` ** `
• 2 ** 3 = 8
• 2.0 ** 3 = 8.0
• 2.0 ** -3 = 0.125 (ie 1/8)
• 2 ** -3 gives a compilation error

### Other Operators

• Not equal is /= (not !=)

• Boolean: and, or, xor, not
• Parentheses required when using more than one of and, or, xor

• String concatenation: &
• Overloaded for characters: 'a' & 'b' = "ab"
• Overloaded for characters and strings: 'a' & "b" = "a" & 'b' = "ab"

• Short circuit: And then, Or else
• Only evaluate second operator if necessary

### Unary Minus

• Sometimes extra parentheses are required for unary minus:
• ```    x := x + (-2);
x := x * (-2);
x := x mod (-2);
x := (-2) mod 12;
```
• Notice that -2 ** 4 means -(2**4) and not (-2)**4.

### Literals

• Underscores can be used (eg ...)
• Example: ```Pi: Constant := 3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37510;```

• Floats must begin and end with a digit (eg ...)

• Different bases are possible:
• Binary: 2#1100_1000#
• Hex: 16#BF3F#
• Fractional: 2#11.01# is 3.25 decimal
• 2#11.01#E+3 is same as 2#11010#

• Other literals:
• Character: use single quotes (eg 'b')
• String: use double quotes (eg "Hi Mom")
• New literals: enumerated types
• Example:
• ```            type color is (red, blue, green);
c: color := blue;
...
if c = red then ...  ```

### Numeric Output

• Numeric IO packages for integers and floats
• Why integer_TEXT_io?
• Because we convert from binary integer format to text format (on output)
• Because we convert to binary integer format from text format (on input)

• Integer and float `put` allow format control
• Ada.integer_text_io.put has a width parameter
• put(n);
• put(n, 5); -- minimum width is 5

• ada.float_text_io.put has fore, aft, exp parameters
• ` fore` is minimum number of places before the decimal
• ` aft` is number of places after the decimal
• ` exp` is minimum number of places for the exponent

### Keyword Parameters

• Positional parameters are matched by order
• put(n, 5); -- n matched with parameter item, 5 with width

• Keyword parameters are matched by name
• `put(item => n, width => 5); `
• `put(width => 5, item => n); `
• ` put(item =>x, fore=>5, aft=>2, exp=>0);`

• Can mix positional and keyword: positional must be first
• put(n, width => 5);

### Default Parameters

• Parameters can have default values

• Example: for new_line, the default is 1

• For integer_text_io, the default width is 11 (big enough for 2 billion and a sign)

### More on the Use Statement

• Sometimes it's useful to include the package name to know what package is being referenced
• But, `Ada.Integer_text_io.put` is long
• Can say ` use Ada` and then say Integer_text_io.put

### Type Attributes and Some Other Types

• `'img` and `'image` are attributes
• they are like toString

• variable'img provided by gnat, it's not standard Ada
• Most types allow 'img and 'image

• We'll see more attributes later, for example:
• Integer'value is inverse of 'image (eg Integer'value("456"))

• Integer'first - the smallest integer
• Integer'last - the largest integer
• Integer'range - the range from smallest to largest integer

• Character'val(65) - Character whose position is 65
• Character'pos('A') - position of 'A' in the set of Characters

• Boolean'val(0) - Boolean value at position 0 (ie false) in the set of Boolean values
• Boolean'pos(true) - Position of true (ie 1)

• Ceiling, floor, round
• f := Float'ceiling(1.1);
• f := Float'floor(1.9);
• f := Float'rounding(1.9);
• f := Float'rounding(1.5);
• f := Float'rounding(-1.5);

### Strong Type Checking

• Strong type checking:
• Ensures that operations have valid operands
• Occurs on assignment, procedure calls, and arithmetic operations
• ```        // Java
int sum;
double av;                 // 64 bit floating point

// Assignment
av = 3;                    // Type mismatch, but compiles
av = sum / 3;              // Type mismatch, but compiles

// Method calls
av = java.Math.sqrt(3);    // Type mismatch, but compiles

// Arithmetic operations
av = sum / 3.0;            // Type mismatch, but compiles

--------------------------------------
sum: Integer;
av: float;  -- 32 bit floating point

-- Assignment
av := 3;                     -- Type mismatch.  Does not compile
av := sum / 3;               -- Type mismatch.  Does not compile

-- Procedure parameters
Ada.Float_Text_IO.put(3);    -- Type mismatch.  Does not compile

-- Arithmetic operation
av := sum / 3.0;             -- Type mismatch.  Does not compile
```

### Implicit and Explicit Conversions

• Java does implict conversion; Ada does not
• In the examples above, ints are implicitly converted to doubles
• The Java code below shows the equivalent explicit conversions
• The Ada code below shows the required explicit conversions
• ```        // Java

// Assignment
av = (double) 3;           // Explicit conversion int to double
av = (double) (sum / 3);   // Explicit conversion int to double

// Method calls
av = java.Math.sqrt((double)3);    // Explicit conversion int to double

// Arithmetic operations
av = sum / 3.0;           // Explicit conversion int to double

--------------------------------------

-- Assignment
av := float(3);           -- Explicit conversion
av := float(sum / 3);     -- Explicit conversion

-- Procedure parameters

-- Arithmetic operator
av := float(sum) / 3.0;   -- Explicit conversion
```

### Caution: Conversions and Integer and Floating Point Conversion

• Make sure that you understand the difference between these two:
• ```        av := float(sum) / float(3);

av := float(sum / 3);
```
• What happens in this Java code?
• ```        av = sum / 3;
```

### Type Checking Rules

• Both sides of assignment must match
• Formal and actual parameters must match
• Operands of arithmetic operators must match

• No implicit conversion between Integers and Floats
• Java does implicit widening conversion, Ada does not
• Explicit conversion is required

• There are slightly different rules for subtypes

### Type Checking and I/O

• Must do IO with correct routine
• ```        -- Ada                            // Java