2  Hello

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.

Real or Floating Types

~/bin/dtypes float
dtypes dtypes.adb Compiled Dec 02 2024 05:14:54
--------- dtypes.Float_Types
Float                  Size             32 bits
Float                  Range           -3.40282E+38 ..  3.40282E+38
Float                  Model_Small      1.17549E-38
Long_Float             Size             64 bits
Long_Float             Range           -1.79769313486232E+308 ..  1.79769313486232E+308
Float                  Model_Small      2.22507385850720E-308
Long_Long_Float        Size             64 bits
Long_Long_Float        Range           -1.79769313486232E+308 ..  1.79769313486232E+308
Float                  Model_Small      2.22507385850720E-308

Enumeration

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:

~/bin/codemd ..//Prj/dtypes/src/dtypes.adb -x IntTypes -l
0042 |       Annotation ("Integer", "Size");
0043 |       Put (Integer'(Integer'Size)'Image);
0044 |       Put_Line (" bits");
0045 |       Annotation ("Integer", "Range");
0046 |       Put (Integer'(Integer'First)'Image);
0047 |       Put (" .. ");
0048 |       Put (Integer'(Integer'Last)'Image);
0049 |       New_Line;
0050 | 
0051 |       Annotation ("Short_Integer", "Size");
0052 |       Put (Integer'(Short_Integer'Size)'Image);
0053 |       Put_Line (" bits");
0054 |       Annotation ("Short_Integer", "Range");
0055 |       Put (Integer (Short_Integer'First)'Image);
0056 |       Put (" .. ");
0057 |       Put (Integer (Short_Integer'Last)'Image);
0058 |       New_Line;
0059 | 
0060 |       Annotation ("Short_Short_Integer", "Size");
0061 |       Put (Integer'(Short_Short_Integer'Size)'Image);
0062 |       Put_Line (" bits");
0063 |       Annotation ("Short_Short_Integer", "Range");
0064 |       Put (Integer (Short_Short_Integer'First)'Image);
0065 |       Put (" .. ");
0066 |       Put (Integer (Short_Short_Integer'Last)'Image);
0067 |       New_Line;
0068 | 
0069 |       Annotation ("Long_Integer", "Size");
0070 |       Put (Long_Integer'(Long_Integer'Size)'Image);
0071 |       Put_Line (" bits");
0072 |       Annotation ("Long_Integer", "Range");
0073 |       Put (Long_Integer (Long_Integer'First)'Image);
0074 |       Put (" .. ");
0075 |       Put (Long_Integer (Long_Integer'Last)'Image);
0076 |       New_Line;
0077 | 

The enumeration data type examples shown above are supported by the language with richer set of attributes:

~/bin/codemd ../Prj/dtypes/src/dtypes.adb -x EnumTypes -l
0205 |       Annotation ("Character", "Range");
0206 |       Put (Character (Character'First)'Image);
0207 |       Put (" .. ");
0208 |       Put (Character'(Character'Last)'Image);
0209 |       New_Line;
0210 | 
0211 |       Annotation ("Character <CR>", "Internal");
0212 |       Put (Integer'(Character'Pos (ASCII.CR))'Image);
0213 |       New_Line;
0214 | 
0215 |       Annotation ("Character <CR>", "Image");
0216 |       Put (Character'Image (ASCII.CR));
0217 |       New_Line;
0218 | 
0219 |       Annotation ("Character $ ", "Internal");
0220 |       Put (Integer'(Character'Pos ('$'))'Image);
0221 |       New_Line;
0222 | 
0223 |       Annotation ("Character $", "Succ, Pred");
0224 |       Put (Character'Succ ('$'));
0225 |       Put (" ; ");
0226 |       Put (Character'Pred ('$'));
0227 |       New_Line;
0228 | 

The String data type illustrates leads to questions about the runtime support for various string operations.

~/bin/codemd ../Prj/dtypes/src/dtypes.adb -x StrType -l
0257 |          Annotation ("Candidate String ");
0258 |          Put_Line (str);
0259 |          Annotation ("Length ");
0260 |          Put_Line (Positive'(str'Length)'Image);
0261 |          Annotation ("Size in bits ");
0262 |          Put_Line (Positive'(str'Size)'Image);
0263 |          Annotation ("Truncate to first half ");
0264 |          Put_Line (str (1 .. str'Length / 2));
0265 |          Annotation ("Mid half ");
0266 |          Put_Line (str (1 + str'Length / 4 .. 3 * str'Length / 4));
0267 |          Annotation ("Multiply ");
0268 |          Put_Line (str & str);
0269 |          Annotation ("Occurrences of 'a'");
0270 |          Put_Line (Fixed.Count (str, "a")'Image);
0271 |          Annotation ("Position of 'cal'");
0272 |          Put_Line (Fixed.Index (str, "cal")'Image);
0273 |          Annotation ("Head ");
0274 |          Put (Fixed.Head (str, 48));
0275 |          Put_Line (";");
0276 |          Annotation ("Tail ");
0277 |          Put (Fixed.Tail (str, 48));
0278 |          Put_Line (";");
0279 |          Annotation ("To Upper Case ");
0280 |          Put_Line (Fixed.Translate (str, Maps.Constants.Upper_Case_Map));

In addition to attributes, all data types have rich support in the predefined library. A small set of libraries is required to support this project.

~/bin/codemd ../Prj/dtypes/src/dtypes.adb -x Library -l
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

Delared and processed by the code fragment:

~/bin/codemd ../Prj/dtypes/src/arr.adb -x Constrained -l
0038 |       charcounts : array (Character'First .. Character'Last) of Integer :=
0039 |         (others => 0);

and

~/bin/codemd ../Prj/dtypes/src/arr.adb -x ForEachChar -l

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

implemented as:

~/bin/codemd ../Prj/dtypes/src/arr.adb -x ArrTypeFloat -l
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.

Unsigned Integer Arrays

~/bin/arr uns
arr arr.adb Compiled Nov 12 2024 05:54:52
--------- arr.Unsigned_Array
Candidate              :  7
                       Digitised        7, 
                       Reconstructed    7
Candidate              :  99
                       Digitised        9,  9, 
                       Reconstructed    99
Candidate              :  199
                       Digitised        1,  9,  9, 
                       Reconstructed    199
Candidate              :  244
                       Digitised        2,  4,  4, 
                       Reconstructed    244

implemented as :

~/bin/codemd ../Prj/dtypes/src/arr.adb -x ArrTypeUns -l
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.

2.4 Sample Implementation

Repository: TechAdaBook
Directory: Prj/dtypes