Whirlwind Tour of Ada - Part 2a
Working with Primitive Types
average.adb
Primitive Types, Operators, Literals
Numeric Output, Keyword and Default Parameters
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
- 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
average.adb
- Program average.adb (prettified)
- 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
Highest ** abs not
Multiplying * / rem mod
Unary adding + -
Binary adding + - &
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
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
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
- Example: attributes.adb and prettified
-
'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
- Ada is more strongly typed than Ada
// 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
--------------------------------------
-- Ada
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
--------------------------------------
-- Ada
-- Assignment
av := float(3); -- Explicit conversion
av := float(sum / 3); -- Explicit conversion
-- Procedure parameters
Ada.Float_Text_IO.put(float(3)); -- Explicit conversion
-- 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
- Ada 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
ada.integer_text_io.put(i); System.out.print(i);
ada.float_text_io.put(a); System.out.print(a);