In the grand old tradition of learning programming, we start with our version of the hello world. Our journey commences with the understanding of the toolbox, particularly those features that scientific computation will rely upon. Printouts to the terminal, basic data types and their features, simple numerical functions are the subject of the projectlets in this chapter. Stretching a bit further, a review of the array as a fundamental data structure is studied.
2.1 Learning Objectives
Understand the fundamental data types supported by the language.
Text output of simple variables of diverse data types
Characteristics of the data types like storage occupied, range of values
Arrays and their handling
2.2 Data Types
2.2.1 Projectlet Specification
Printout the size in number of bits, range for fundamental data types.
2.2.2 Sample Runs
Integer Types
~/bin/dtypes int
dtypes dtypes.adb Compiled Dec 02 2024 05:14:54
--------- dtypes.Integer_Types
Integer Size 32 bits
Integer Range -2147483648 .. 2147483647
Short_Integer Size 16 bits
Short_Integer Range -32768 .. 32767
Short_Short_Integer Size 8 bits
Short_Short_Integer Range -128 .. 127
Long_Integer Size 64 bits
Long_Integer Range -9223372036854775808 .. 9223372036854775807
As shown above, integer datatypes of 8,16,32 and 64 bits are supported. For each of these types, some key parameters are also shown. For example with an 8 bit Integer, values are in the range -32768 .. 32767. In particular these integer types are signed.
Unsigned Integer Types
~//bin/dtypes uns
dtypes dtypes.adb Compiled Dec 02 2024 05:14:54
--------- dtypes.Unsigned_Types
Unsigned_32 Size 32 bits
Unsigned_32 Range 0 .. 4294967295
Unsigned_16 Size 16 bits
Unsigned_16 Range 0 .. 65535
Unsigned_8 Size 8 bits
Unsigned_8 Range 0 .. 255
Unsigned_64 Size 64 bits
Unsigned_64 Range 0 .. 18446744073709551615
Natural Size 31 bits
Natural Range 0 .. 2147483647
Positive Size 31 bits
Positive Range 1 .. 2147483647
Corresponding to each of the bit sizes, there are also unsigned integer types as shown above.
In Ada, enumeration is a full fledged data type instead of being an alternate way of looking at groups of integers.
~/bin/dtypes enum
dtypes dtypes.adb Compiled Dec 02 2024 05:14:54
--------- dtypes.Enumeration_Types
Character Size 8 bits
Character Range NUL .. 'ÿ'
Character <CR> Internal 13
Character <CR> Image CR
Character $ Internal 36
Character $ Succ, Pred % ; #
Boolean Size 1 bits
Boolean Machine_Size 8 bits
Day_Name Size 3 bits
Day_Name Machine_Size 8 bits
The above illustrates that Character, Boolean are enumerations as well as the names of Week Days. Of particular note is that the enumerations have a Machine_Size representing the number of bits allocated versus Size which is the minimum size required for this data type. These will become significant when data structures include members of these data types and the compiler has the option to optimize the storage.
String
In Ada the string is an array of Characters. Unlike C normal strings do not have a null termination requirement. Instead Strings are of fixed length determined at the time of creation of a string. This treatment of strings and other such data types is the cornerstone of safe programming practices imposed by the language.
~/bin/dtypes str
dtypes dtypes.adb Compiled Dec 02 2024 05:14:54
--------- dtypes.String_Type
Candidate String : ~!@#$%^&*()_+`234567890-=
Length : 25
Size in bits : 200
Truncate to first half : ~!@#$%^&*()_
Mid half : ^&*()_+`2345
Multiply : ~!@#$%^&*()_+`234567890-=~!@#$%^&*()_+`234567890-=
Occurrences of 'a' : 0
Position of 'cal' : 0
Head : ~!@#$%^&*()_+`234567890-= ;
Tail : ~!@#$%^&*()_+`234567890-=;
To Upper Case : ~!@#$%^&*()_+`234567890-=
Candidate String : alphabetical
Length : 12
Size in bits : 96
Truncate to first half : alphab
Mid half : habeti
Multiply : alphabeticalalphabetical
Occurrences of 'a' : 3
Position of 'cal' : 10
Head : alphabetical ;
Tail : alphabetical;
To Upper Case : ALPHABETICAL
Candidate String : ~!@#$%^&*()_+`234567890-=alphabetical
Length : 37
Size in bits : 296
Truncate to first half : ~!@#$%^&*()_+`2345
Mid half : ()_+`234567890-=al
Multiply : ~!@#$%^&*()_+`234567890-=alphabetical~!@#$%^&*()_+`234567890-=alphabetical
Occurrences of 'a' : 3
Position of 'cal' : 35
Head : ~!@#$%^&*()_+`234567890-=alphabetical ;
Tail : ~!@#$%^&*()_+`234567890-=alphabetical;
To Upper Case : ~!@#$%^&*()_+`234567890-=ALPHABETICAL
2.2.3 Implementation
In languages like C the limits of the data types are defined as language defined macros. E.G INT_MAX and INT_MIN for maximum and minimum of the int data type. In Ada, the vehicle to access such parameters is the concept of attributes. As shown for the Integer data types, all data types support appropriate attributes:
0002 | with Interfaces; use Interfaces;
0003 | with Ada.Text_IO; use Ada.Text_IO;
0004 |
0005 | with Ada.Command_Line; use Ada.Command_Line;
0006 | with Ada.Strings.Fixed;
0007 | with Ada.Strings.Maps.Constants;
0008 |
0009 | with Ada.Calendar.Formatting;
0010 |
0011 | with GNAT.Source_Info; use GNAT.Source_Info;
2.3 Data Structures - Arrays
We encountered a basic array in Strings; Strings are an array of Characters which itself is of the data type Enumeration. Further examples of arrays of Integers, Floats and Unsigned Integers with varying number of elements is illustrated in this projectlet.
Integer Arrays
~/bin/arr int
arr arr.adb Compiled Nov 12 2024 05:54:52
--------- arr.Int_Array
Characters that occurred in the quote
Character ' ' : 19
Character ',' : 1
Character '.' : 1
Character 'E' : 1
Character 'S' : 1
Character 'a' : 10
Character 'b' : 2
Character 'c' : 1
Character 'd' : 5
Character 'e' : 16
Character 'f' : 1
Character 'g' : 4
Character 'h' : 5
Character 'i' : 10
Character 'k' : 2
Character 'l' : 5
Character 'm' : 2
Character 'n' : 11
Character 'o' : 4
Character 'p' : 2
Character 'r' : 9
Character 's' : 7
Character 't' : 10
Character 'u' : 5
Character 'w' : 2
Character 'y' : 1
Some important things to note are the array index which in this case is of type Character. As a result, the iteration over the entire array is syntactically interesting though conceptually normal.
Real Arrays
~/bin/arr real
arr arr.adb Compiled Nov 12 2024 05:54:52
--------- arr.Real_Array
Real Array Length 4
Size 128 bits
Range 1 .. 4
Raise to the Power 3 :
1 1.00000E+00 1.00000E+00
2 1.00000E+01 1.00000E+03
3 1.00000E+02 1.00000E+06
4 1.00000E+03 1.00000E+09
0068 | type Real_Array is array (Integer range <>) of Float;
0069 | args : Real_Array := (1 => 1.0, 2 => 10.0, 3 => 100.0, 4 => 1_000.0);
0070 | procedure Show_Powers (vals : Real_Array; p : Integer) is
0071 | begin
0072 | for v in vals'Range loop
0073 | Put (v'Image);
0074 | Put (ASCII.HT);
0075 | Put (vals (v)'Image);
0076 | Put (ASCII.HT);
0077 | Put (Float'(vals (v)**p)'Image);
0078 | New_Line;
0079 | end loop;
0080 | end Show_Powers;
This example illustrates constraining of the array (ie specifying the limits of the array) implicitly by initialization. The array limits are static though the contents can be changed in this example.
0105 | type Unsigned_Array is array (Integer range <>) of Unsigned_8;
0106 | subtype DecimalDigits_Array is Unsigned_Array (1 .. 11);
0107 | candidates : Unsigned_Array (1 .. 4) := (7, 99, 199, 244);
0108 |
0109 | function Digitize (val : Unsigned_8) return DecimalDigits_Array is
0110 | result : DecimalDigits_Array := (others => 0);
0111 | dp : Integer := 0;
0112 | valnow : Unsigned_8 := val;
0113 | begin
0114 | while valnow > 0 loop
0115 | result (result'Last - dp) := valnow rem 10;
0116 | dp := dp + 1;
0117 | valnow := valnow / 10;
0118 | end loop;
0119 | return result;
0120 | end Digitize;
0121 |
0122 | function Value (val : DecimalDigits_Array) return Unsigned_8 is
0123 | result : Unsigned_8 := 0;
0124 | begin
0125 | for d in val'Range loop
0126 | result := result * 10 + val (d);
0127 | end loop;
0128 | return result;
0129 | end Value;
0130 |
0131 | procedure Show (vals : Unsigned_Array) is
0132 | significant : Boolean := False;
0133 | begin
0134 | for v in vals'Range loop
0135 | if significant then
0136 | Put (vals (v)'Image);
0137 | Put (", ");
0138 | elsif vals (v) > 0 then
0139 | significant := True;
0140 | Put (vals (v)'Image);
0141 | Put (", ");
0142 | end if;
0143 | end loop;
0144 | if not significant then
0145 | Put ("0");
0146 | end if;
0147 | end Show;
In this case, a function is defined that returns an array type. The arrays are passed around like any variable of any other data type and the callee can query the limits (though not the data types) at runtime.