Ada Fundamentals  Primitive Types
Overview
 Integer and Float Types
 Integer'Image and Float'Image
 Ada.Integer_Text_io; Ada.Float_Text_io
 Other Primitive Types
 Very Strong Type Checking
 Type Conversions
 Language comparison
 Subtype conversion
 Operators
Example Program (From Last Year)
 Let's get some practice by writing a simple program
 Let's sum a group of integers and calculate and print their average
 First we'll input the number of numbers and read that many numbers
 Can we format the average of the numbers
 What if the numbers are floating point?
 Let's make sure the number of numbers is nonnegative
 Now let's read until eof
Integer'Image  An Attribute of type Integer
 Similar to Java
toString()
method
 Resulting string includes space for a sign.
 This results in a leading blank for positive numbers
 'Image is an attribute of the type Integer
 Most builtin types have 'Image attribute
Package Ada.Integer_Text_IO
 Integer input and output routines
 Name comes from outputing an integer as text
 Routine
put
is overloaded (ie same name
but different parameters)
 Ada.Text_IO.put("HI");
 Ada.Integer_Text_IO.put(i);
 If two packages have the same routine with the
same parameter list, then the package name must
be used to disambiguate the routines
 Can a single package have two routines with
the same name and same parameter list?
 Minimum width  eg put(i, 1)
 If given 2 parameters, the second is the minimum
width
 Pads on left with blanks if needed
 Examples:
i := 37;
12345678901
put(i, 5);  37
put(i, 1); 37
put(i);  37
 Default width is 11
Integer Input: Ada.Integer_Text_IO.get
 How to input an Integer?
 Consider this Java:
Scanner s = ...
int i = s.nextInt(); // nextInt returns an int
S.o.println(i);
And this similar Ada code
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure getInt is
i: Integer := 2;
begin
put("Enter an integer: ");  Let's use a prompt
get(i);  Now input the int
put(i);
new_line;
end getInt;
What's unusual about get
Functions are used as values
Procedures are used as statements
Procedure parameters can be changed!
Size Attribute
 How can we tell how many bits a variable takes?
 Attribute size
 Example:
Integer'size
Sizes of Integer Types
 Sizes of types are NOT defined by the language
(unlike Java)
 Floating point sizes
 Values of type Integer are typically 32 bits
 Values of type Long_Integer are 64 bits (on gnat)
 Values of type Long_Long_Integer are 64 bits (on gnat)
Floating Point Types
 Floating point sizes (eg value of Float'size)
 Type
Float
 32 bits on gnat
 Type
Long_Float
 64 bits on gnat
 Type
Long_Long_Float
 96 bits on gnat
 Floating point types trade precision for range
 32 bit Integer has 10 significant digits in range
± 10^{10}
 32 bit Float has about 6 significant digits for numbers as
small as ± 10^{26} and as large as ±
10^{25}
 Some attributes for floating point types:
 float'small  smallest possible (positive) value
 float'large  largest possible value
 float'digits  number of digits of precision
Package Ada.Float_Text_IO
 Contains routines for IO of floating point types
 put(x)
 default format: scientific notation
 put(x, 3, 4, 1): fore, aft, exp
 fore: minimum digits to left of decimal point
 aft: digits to right of decimal point
 exp: digits in exponent  0 means no exponent
Primitive Types
 Integer and Float are primitive types
 In this context, "primitive" means part of the language; that is, not user defined)
 Other primitive types include
 Character: 8 bit (Wide_Character: 16 bit Unicode, Wide_Wide_Character: 32 bit)
 Boolean: values
true
and false
 Positive: range 1 .. Integer'Last
 Natural: range 0 .. Integer'Last
 String
 Later we will see that
 Character and Boolean are Enumerated types
 String is an array of characters
 Positive and Natural are actually subtypes of Integer
 Where do we see subtypes in Java?
 Below we see difference in subtype conversion in Ada and Java
Another Meaning of Primitive
 What are the two kinds of types in Java?
 Reference type:
 variable stores a reference to a value
 automatic dereferencing
 Primitive: variable stores value itself
 Ada builtin types are primitive (ie not reference)
 Later we will see that a value of a primitive type can be a pointer
 User defined types
 In Java: all user defined types are ...
 In Ada: user defined types can be primitive
Very Strong Type Checking
 Ada has different and generally stronger type checking
rules than Java
 Types of right and left sides of assignment must match
 x: Float := 3;  Compile error
 Java would do an implicit conversion
 Arithmetic operators must have the same types on both sides
 y := 2 + 3.0;  Compile error
 Java would do an implicit conversion
 Later we will see numeric subtypes that have more flexible rules:

Ada will do implicit conversion on numeric subtypes (eg from natural to integer)
Explicit Type Conversion
 Example  this won't compile  it contains type mismatch:
i: Integer;
f, g: Float;
...
g := f + i;
Ada will not do an implicit conversion between integer and float
Example: the explicit type conversion fixes the type mismatch:
i: Integer;
f, g: Float;
...
i := 99;
...
g := f + Float(i);
 float(i) returns the value of i as a float
 that is, it returns 99.0
In general, a type conversion uses the name of a type as if it were a function
that takes a value of one type and returns a value of a different, related type
Similar to a java type cast (eg g = f + (float) i;)
Language Comparison: Implicit and Explicit Type Conversion
 Ada will not do an implicit type conversion from integer to float
 Java will do an implicit type conversion from integer to float
 C will do an implicit type conversion from integer to float and float to integer
 C++ will do an implicit type conversion from integer to float
 C++ will do an implicit type conversion from float to integer and give a
warning
Language Comparison: Type Conversion with Subtypes in Ada and Java
 Ada will do an implicit type conversion between a subtype of a type and the
type (eg from natural to integer, and integer to natural)
 A constraint error is raised if the value of the parent type is not
valid for the subtype
 Java has rules for subtypes and parent types with inheritance
 Parent myP; Child myC;
 myP = myC; //??
 myC = myP; //??
Operators: Precedence and Associativity
Highest  ** abs not  exponent, absolute value,
logical negation 
Multiplying  * / mod rem  mod and rem
differ for negative numbers 
Unary adding  +   
Binary adding  +  &  &
is string concatenation 
Relational  = /= < <= > >=  Note:
not equal is /= rather than != 
Boolean (Lowest)  and or xor 
xor is exclusive or 
 All operators are left associative (but
sometimes parens are required, anyway)
 Later we will see: in, and then, or else
 They are used like operators but they are not called
operators
Examples using Arithmetic Operators
 6 / 2 yields 3
 6.0 / 2.0 yields 3.0
 6.0 / 2 does not compile
 most operators require operands to be of the same type
 2.0 ** 3 yields 8.0
 2.0 ** (3) yields 0.125 (ie 1/8)
Rem and Mod Operators
 Rem and Mod give the same result for positive operands
 Rem and Mod can differ for negative operands
 Table showing examples:
A B  A/B A rem B A mod B  A B  A/B A rem B A mod B

10 5  2 0 0  10 5  2 0 0
11 5  2 1 1  11 5  2 1 4
12 5  2 2 2  12 5  2 2 3
13 5  2 3 3  13 5  2 3 2
14 5  2 4 4  14 5  2 4 1

10 5  2 0 0  10 5  2 0 0
11 5  2 1 4  11 5  2 1 1
12 5  2 2 3  12 5  2 2 2
13 5  2 3 2  13 5  2 3 3
14 5  2 4 1  14 5  2 4 4
Careful: Rem and mod have higher precedence
than unary minus so 3 mod 4 means (3 mod 4)
Rem Operator
 Integer division and Rem work together so that this
identity is true:
A = (A / B) * B + A rem B
 Integer division truncates toward 0 [eg
7/2 = (7)/(2) = 3 and (7)/2 = 7/(2) = 3]
 Rem is designed to work with this definition [eg
7 rem 2 = 7 rem (2) = 1 and (7) rem 2 = 7 rem (2) = 1]
 Example showing A = (A / B) * B + A rem B:
(A / B) * B + A rem B
= (7 / 2) * 2 + 7 rem 2
= 3 * 2 + 1
= 6 + 1
= 7
The result of A rem B has the sign of the Dividend
Mod Operator
 Mod provides modular behavior (ie clock arithmetic):
 Example: 9 mod 12 = 3 (ie go around the clock 9 hours counterclockwise).
 What is 9 rem 12?
 A mod B is always between 0 and B
 Thus, the result of Mod has the sign of the Divisor
 Does Mod satisfy the identity A = (A/B)*B + A mod B ?
 Not with the built in definition of / [ie A/B truncates toward
0 for integers A and B]
 Yes if A/B truncates toward minus infinity for ints A and B
 In other words, if A/B = integer(float'floor(float(A) /
float(B)))
 Example using truncation toward minus infinity
[eg using (9)/12=1]:
(9/12) * 12 + 9 mod 12
= 1 * 12 + 3
= 12 + 3
= 9
Mod is designed so that A mod B = (A + K*B) mod B, for any integer K
Mod is designed so that A = B*N + A mod B, for some integer N
A Final Word on Integer Division
 How is integer (eg 5 / 4) division defined in math?
 Answer: It gives a rational result, which then has an operator
applied to it
 Example: 5/4 is the rational number one and one quarter
 In Ada, division of integers A and B is defined as
trunc(A/B), for the rational number A/B [trunc removes the fractional part]
Rem and Mod and Other Languages
 In the C/C++/Java family, / is integer division and % is
 In the C/C++/Java family, / for integer division truncates toward 0
 % works with /, like the Ada rem operator
 In virtually all modern processors integer division truncates
toward 0
 Most languages define integer division like Ada and Java, but
other definitions exist!
Examples using Relational and Boolean Operators
 When
and
and or
are mixed, parens
are required (ie user must specify order of
evaluation)
 Example:
if (a < b or c < d) and e <
f then
 Parens are also required if multiple relational operators are
used:
 Example:
if (a < b) = true then
Example using String Concatenation Operator
put_line("Hello, this certainly is a "
& "really long line!");
Short Circuit: and then, or else

and then
and or else
are short circuit versions of and
and or
 Short circuit control forms don't evaluate the right operand if the result
is known from the left operand
 NonShort circuit operators always evaluate both operands
 Examples:
if d /= 0 and then (n / d) > 3 then ...
if x = null or else x.value = probe then ...
Good for processing linked data structures!
Java: What do these do?
if (a == b && c++ == d) ...
if (a == b & c++ == d) ...
in Membership Test
if i in 1 .. 10 then