From 2f0d9930df82cec42e266bcb2c2ca2bf65666fbc Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:12:26 -0300 Subject: [PATCH 01/28] Adding integer type for overlay Type declaration was missing. --- content/courses/advanced-ada/parts/data_types/numerics.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index c7cbd2b24..d0f8c8943 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3394,6 +3394,9 @@ the :ada:`Custom_Decimal_Types` package: type Int_T2_D6 is range -2 ** (T2_D6'Size - 1) .. 2 ** (T2_D6'Size - 1) - 1; + type Int_T2_D12 is + range -2 ** (T2_D12'Size - 1) .. + 2 ** (T2_D12'Size - 1) - 1; end Custom_Decimal_Types; From 818bd9a3d3802ed67afd247c94b4fbe2bbd3056b Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:14:12 -0300 Subject: [PATCH 02/28] Adding Gen_Show_Info procedure --- .../parts/data_types/numerics.rst | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index d0f8c8943..141baa5b0 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3403,6 +3403,56 @@ the :ada:`Custom_Decimal_Types` package: We can use an overlay to uncover the actual integer values stored on the machine when assigning values to objects of decimal type. For example: +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types + + generic + type T_Decimal is delta <> digits <>; + type T_Int_Decimal is range <>; + procedure Gen_Show_Info (V : T_Decimal; + V_Str : String); + + with Ada.Text_IO; use Ada.Text_IO; + + procedure Gen_Show_Info (V : T_Decimal; + V_Str : String) + is + V_Int_Overlay : T_Int_Decimal + with Address => V'Address, + Import, Volatile; + V_Real : Float; + begin + V_Real := Float (V_Int_Overlay) * + T_Decimal'Small; + + Put_Line (V_Str + & " (fixed-point) : " + & V'Image); + Put_Line (V_Str + & " (integer) : " + & V_Int_Overlay'Image); + Put_Line (V_Str + & " (floating-p.) : " + & V_Real'Image); + Put_Line ("----------"); + end Gen_Show_Info; + + with Gen_Show_Info; + + package Custom_Decimal_Types.Show_Info_Procs is + + procedure Show_Info is new + Gen_Show_Info (T_Decimal => T0_D4, + T_Int_Decimal => Int_T0_D4); + procedure Show_Info is new + Gen_Show_Info (T_Decimal => T2_D6, + T_Int_Decimal => Int_T2_D6); + procedure Show_Info is new + Gen_Show_Info (T_Decimal => T2_D12, + T_Int_Decimal => Int_T2_D12); + + end Custom_Decimal_Types.Show_Info_Procs; + + .. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types :class: ada-run From 38b78de2a265311e3c1edb1e9c0d4f6ddc925e26 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:18:11 -0300 Subject: [PATCH 03/28] Replace calls to `Put_Line` by `Show_Info` --- .../parts/data_types/numerics.rst | 62 ++++--------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 141baa5b0..e3ce077d5 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3461,57 +3461,21 @@ machine when assigning values to objects of decimal type. For example: with Custom_Decimal_Types; use Custom_Decimal_Types; - procedure Show_Machine_Implementation is - V_T0_D4 : T0_D4; - V_Int_T0_D4 : Int_T0_D4 - with Address => V_T0_D4'Address, - Import, Volatile; + with Custom_Decimal_Types.Show_Info_Procs; + use Custom_Decimal_Types.Show_Info_Procs; - V_T2_D6 : T2_D6; - V_Int_T2_D6 : Int_T2_D6 - with Address => V_T2_D6'Address, - Import, Volatile; + procedure Show_Machine_Implementation is begin - V_T0_D4 := 1.0; - Put_Line ("1.0 (T0_D4) : " - & V_T0_D4'Image); - Put_Line ("1.0 (Int_T0_D4) : " - & V_Int_T0_D4'Image); - - V_T2_D6 := 1.55; - V_T0_D4 := T0_D4 (V_T2_D6); - Put_Line ("1.55 (T0_D4) : " - & V_T0_D4'Image); - Put_Line ("1.55 (Int_T0_D4) : " - & V_Int_T0_D4'Image); - - V_T0_D4 := 2.0; - Put_Line ("2.0 (T0_D4) : " - & V_T0_D4'Image); - Put_Line ("2.0 (Int_T0_D4) : " - & V_Int_T0_D4'Image); - - Put_Line ("-----------------------------"); - - V_T2_D6 := 1.0; - Put_Line ("1.00 (T2_D6) : " - & V_T2_D6'Image); - Put_Line ("1.00 (Int_T2_D6) : " - & V_Int_T2_D6'Image); - - V_T2_D6 := 1.55; - Put_Line ("1.55 (T2_D6) : " - & V_T2_D6'Image); - Put_Line ("1.55 (Int_T2_D6) : " - & V_Int_T2_D6'Image); - - V_T2_D6 := 2.0; - Put_Line ("2.00 (T2_D6) : " - & V_T2_D6'Image); - Put_Line ("2.00 (Int_T2_D6) : " - & V_Int_T2_D6'Image); - - Put_Line ("-----------------------------"); + + Show_Info (T0_D4'(1.0), "1.0 "); + Show_Info (T0_D4 (T2_D6'(1.55)), + "1.55 "); + Show_Info (T0_D4'(2.0), "2.0 "); + + + Show_Info (T2_D6'(1.0), "1.0 "); + Show_Info (T2_D6'(1.55), "1.55 "); + Show_Info (T2_D6'(2.0), "2.0 "); end Show_Machine_Implementation; In this example, we use the overlays :ada:`V_Int_T0_D4` and :ada:`V_Int_T2_D6` From 65fd5214fe675bca1a241c94e1beb59282b613e4 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:19:52 -0300 Subject: [PATCH 04/28] Add headers to code example --- content/courses/advanced-ada/parts/data_types/numerics.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index e3ce077d5..cc2f44fab 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3466,12 +3466,18 @@ machine when assigning values to objects of decimal type. For example: procedure Show_Machine_Implementation is begin + Put_Line ("============================="); + Put_Line ("T0_D4"); + Put_Line ("============================="); Show_Info (T0_D4'(1.0), "1.0 "); Show_Info (T0_D4 (T2_D6'(1.55)), "1.55 "); Show_Info (T0_D4'(2.0), "2.0 "); + Put_Line ("============================="); + Put_Line ("T2_D6"); + Put_Line ("============================="); Show_Info (T2_D6'(1.0), "1.0 "); Show_Info (T2_D6'(1.55), "1.55 "); From f6f52315e8ebca58c8fb54f71ee4c7da4ad42d41 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:26:27 -0300 Subject: [PATCH 05/28] Adapting explanation after changes to code example --- .../advanced-ada/parts/data_types/numerics.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index cc2f44fab..a2babc2d4 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3401,7 +3401,7 @@ the :ada:`Custom_Decimal_Types` package: end Custom_Decimal_Types; We can use an overlay to uncover the actual integer values stored on the -machine when assigning values to objects of decimal type. For example: +machine for objects of decimal type. For example: .. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types @@ -3452,6 +3452,14 @@ machine when assigning values to objects of decimal type. For example: end Custom_Decimal_Types.Show_Info_Procs; +In this example, we use the overlays :ada:`V_Int_Overlay` in the generic +procedure :ada:`Gen_Show_Info`. This allows us to retrieve the integer +representation of the decimal input variable :ada:`V`. We instantiate this +generic procedure for the :ada:`T0_D4` and :ada:`T2_D6` types (see +:ada:`Show_Info` procedures). + +We can then call :ada:`Show_Info` for a few values. By doing so, we see +the machine representation of those decimal values. For example: .. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types :class: ada-run @@ -3484,11 +3492,7 @@ machine when assigning values to objects of decimal type. For example: Show_Info (T2_D6'(2.0), "2.0 "); end Show_Machine_Implementation; -In this example, we use the overlays :ada:`V_Int_T0_D4` and :ada:`V_Int_T2_D6` -to retrieve the integer representation of the decimal variables :ada:`V_T0_D4` -and :ada:`V_T2_D6`. By doing this, we retrieve the machine representation of -the real values for the :ada:`T0_D4` and :ada:`T2_D6` types. The table shows -the values that we get by running the test application: +The table shows the values that we get by running the test application: +-------------+-----------------------------+ | Real value | Integer representation | From 531bbc9a6d5108c41fe77f365b08aa8a5f1b9e51 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 14 Feb 2026 18:38:59 -0300 Subject: [PATCH 06/28] Editorial change: Machine_Implementation => Machine_Representation --- .../courses/advanced-ada/parts/data_types/numerics.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index a2babc2d4..357dac883 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3377,7 +3377,7 @@ Machine representation of decimal types Let's start with decimal fixed-ppint types. Consider the following types from the :ada:`Custom_Decimal_Types` package: -.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types package Custom_Decimal_Types is @@ -3403,7 +3403,7 @@ the :ada:`Custom_Decimal_Types` package: We can use an overlay to uncover the actual integer values stored on the machine for objects of decimal type. For example: -.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types generic type T_Decimal is delta <> digits <>; @@ -3461,7 +3461,7 @@ generic procedure for the :ada:`T0_D4` and :ada:`T2_D6` types (see We can then call :ada:`Show_Info` for a few values. By doing so, we see the machine representation of those decimal values. For example: -.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Implementation_Decimal_Types +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -3472,7 +3472,7 @@ the machine representation of those decimal values. For example: with Custom_Decimal_Types.Show_Info_Procs; use Custom_Decimal_Types.Show_Info_Procs; - procedure Show_Machine_Implementation is + procedure Show_Machine_Representation is begin Put_Line ("============================="); Put_Line ("T0_D4"); @@ -3490,7 +3490,7 @@ the machine representation of those decimal values. For example: Show_Info (T2_D6'(1.0), "1.0 "); Show_Info (T2_D6'(1.55), "1.55 "); Show_Info (T2_D6'(2.0), "2.0 "); - end Show_Machine_Implementation; + end Show_Machine_Representation; The table shows the values that we get by running the test application: From 6f9d362dfe9239d39aba2edabbac14e6e20d034c Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:26:03 -0300 Subject: [PATCH 07/28] Editorial change: correcting typo --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 357dac883..1169141df 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3374,7 +3374,7 @@ retrieve the actual integer representation, we can use Machine representation of decimal types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Let's start with decimal fixed-ppint types. Consider the following types from +Let's start with decimal fixed-point types. Consider the following types from the :ada:`Custom_Decimal_Types` package: .. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types From f2fdcaa5724937a08a3744685ff64121b0c66168 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:26:31 -0300 Subject: [PATCH 08/28] Editorial change: correct button in code example --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 1169141df..b8e947c52 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3403,7 +3403,7 @@ the :ada:`Custom_Decimal_Types` package: We can use an overlay to uncover the actual integer values stored on the machine for objects of decimal type. For example: -.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types generic type T_Decimal is delta <> digits <>; From 5eb930344a59d4fe6cc5eb3d8c0e9929fd3cf2c0 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:26:57 -0300 Subject: [PATCH 09/28] Editorial change: adding empty line in code example --- content/courses/advanced-ada/parts/data_types/numerics.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index b8e947c52..0e4bc2aa2 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3419,6 +3419,7 @@ machine for objects of decimal type. For example: V_Int_Overlay : T_Int_Decimal with Address => V'Address, Import, Volatile; + V_Real : Float; begin V_Real := Float (V_Int_Overlay) * From 9f748d630f9d1cb22bb04954b1f2e006ec9884f3 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:27:35 -0300 Subject: [PATCH 10/28] Mentioning generic procedure --- content/courses/advanced-ada/parts/data_types/numerics.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 0e4bc2aa2..fc64cf45d 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3400,8 +3400,9 @@ the :ada:`Custom_Decimal_Types` package: end Custom_Decimal_Types; -We can use an overlay to uncover the actual integer values stored on the -machine for objects of decimal type. For example: +We can use an overlay in the body of the generic :ada:`Gen_Show_Info` procedure +to uncover the actual integer values stored on the machine for objects of +decimal type. For example: .. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types From 706332c3dc1c0f1ddf0ae891ce353e7134b40cbd Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:27:54 -0300 Subject: [PATCH 11/28] Editorial change: correcting typo --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index fc64cf45d..c4319aec9 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3521,7 +3521,7 @@ which, as we've seen before, is equal to the *delta* for decimal fixed-point types. (Later on, we see that this *detail* makes a difference for ordinary fixed-point types.) -For example, if we multiple the integer representation of the real value by the +For example, if we multiply the integer representation of the real value by the *small*, we get the real value: +-------------+-------------------------------+ From 6350a4c03d1aef469d4951eda7e6a15cb398fc04 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 21:31:23 -0300 Subject: [PATCH 12/28] Editorial change: adding decimal non-exponential version of number --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index c4319aec9..e3845d69a 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3183,7 +3183,7 @@ rule that it must be smaller or equal to the *delta*. For example: end Show_Fixed_Small_Delta; In this example, the *delta* that we specifed for :ada:`Ordinary_Fixed_Point` -is 0.2, while the compiler-selected *small* is 2.0\ :sup:`-3`. +is 0.2, while the compiler-selected *small* is 0.125 (2.0\ :sup:`-3`). .. admonition:: For further reading... From 7e793a0dc6d224271b6396a5daf312910324c17f Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:26:26 -0300 Subject: [PATCH 13/28] Minor editorial change: replacing word --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index e3845d69a..d32ba6284 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3604,7 +3604,7 @@ In this example, we convert the value of :ada:`D` |mdash| from the Conversion to other types ^^^^^^^^^^^^^^^^^^^^^^^^^ -Similarly, we can convert from and to fixed-point types when using +As expected, we can convert from and to fixed-point types when using other numeric types such as integer and floating-point types. Let's see an example for decimal fixed-point types: From 1c0a23fab438df3e2416dbabc34705cfd8995926 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:27:03 -0300 Subject: [PATCH 14/28] Editorial change: adding separators to code example --- content/courses/advanced-ada/parts/data_types/numerics.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index d32ba6284..da1fcd246 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3649,6 +3649,7 @@ Let's see an example for decimal fixed-point types: & D6'Image); Put_Line ("D18 = " & D18'Image); + Put_Line ("-----------------------------"); D18 := TD18 (Decimal'Last); D6 := Decimal (D18); @@ -3660,6 +3661,7 @@ Let's see an example for decimal fixed-point types: & D6'Image); Put_Line ("D18 = " & D18'Image); + Put_Line ("-----------------------------"); D6 := 800.0; D18_1000 := TD18_1000 (D6); From 848f439f1b2312688e64f07c4aafa055453696e5 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:31:18 -0300 Subject: [PATCH 15/28] Editorial change: improving description of decimal type conversion --- .../advanced-ada/parts/data_types/numerics.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index da1fcd246..1df2d6484 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3676,10 +3676,14 @@ Let's see an example for decimal fixed-point types: end Show_Decimal_Type_Conversions; -In this example, we declare the decimal fixed-point type :ada:`Decimal` and the -floating-point type :ada:`TD18`. Conversion between these two types works as -expected: we use :ada:`TD18 (D6)` to convert from a decimal fixed-point type -and :ada:`Decimal (D18)` to convert to a decimal fixed-point type. +In the :ada:`Custom_Types` package, we declare the decimal fixed-point type +:ada:`Decimal`, the floating-point type :ada:`TD18` and the range-constrained +floating-point type :ada:`TD18_1000`. + +Conversion between these three types works as expected, as we see in the +:ada:`Show_Decimal_Type_Conversions` procedure. We use :ada:`TD18 (D6)` and +:ada:`TD18_1000 (D6)` to convert from a decimal fixed-point type, +:ada:`Decimal (D18)` to convert to a decimal fixed-point type. Of course, when converting to a fixed-point type, we have to ensure that the floating-point value is in the range that is suitable for the target From 66f100773dc430b1dadec07e0f6be21aa3bca274 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:32:15 -0300 Subject: [PATCH 16/28] Adding subsection on deriving from ordinary fixed-point types --- .../parts/data_types/numerics.rst | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 1df2d6484..c7b1d0f60 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3282,6 +3282,45 @@ type. Also, :ada:`Small_Money (D)` performs a conversion between decimal fixed-point types (from the :ada:`Decimal` type to the :ada:`Small_Money` type). +Let's now focus on deriving from ordinary fixed-point types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Derived_Ordinary_Fixed_Point_Types + + package Custom_Fixed_Point is + + D : constant := 2.0 ** (-15); + type Short_Fixed is + delta D + range -1.0 .. 1.0 - D; + + type Coefficient is new + Short_Fixed; + + end Custom_Fixed_Point; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Derived_Fixed_Point_Types is + SF : Short_Fixed; + C : Coefficient; + begin + SF := 0.25; + Put_Line ("SF = " + & SF'Image); + + C := Coefficient (SF); + Put_Line ("C = " + & C'Image); + end Show_Derived_Fixed_Point_Types; + +In the :ada:`Show_Derived_Fixed_Point_Types` procedure, we derive the +:ada:`Coefficient` type from the :ada:`Short_Fixed` type. We use +:ada:`Coefficient (SF)` to convert from the :ada:`Short_Fixed` type to the +:ada:`Coefficient` type. + Fixed-point subtypes ^^^^^^^^^^^^^^^^^^^^ From 62502b550105745509e52360de5543d655f885bd Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:34:00 -0300 Subject: [PATCH 17/28] Adding subsection on subtypes of ordinary fixed-point types --- .../parts/data_types/numerics.rst | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index c7b1d0f60..fb42af918 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3360,6 +3360,42 @@ decimal fixed-point types: In this example, we declare :ada:`Small_Money` as a subtype of the :ada:`Decimal` type. +Let's now focus on subtypes of ordinary fixed-point types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Derived_Ordinary_Fixed_Point_Types + + package Custom_Fixed_Point is + + D : constant := 2.0 ** (-15); + type Short_Fixed is + delta D + range -1.0 .. 1.0 - D; + + subtype Coefficient is Short_Fixed; + + end Custom_Fixed_Point; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Fixed_Point_Subtypes is + SF : Short_Fixed; + C : Coefficient; + begin + SF := 0.25; + Put_Line ("SF = " + & SF'Image); + + C := SF; + Put_Line ("C = " + & C'Image); + end Show_Fixed_Point_Subtypes; + +In the :ada:`Show_Fixed_Point_Subtypes` procedure, we declare +:ada:`Coefficient` as a subtype of the :ada:`Short_Fixed` type. + .. _Adv_Ada_Fixed_Point_Type_Size: From e01f05ec6177a0b94f7f366f62e87e0103f6d880 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:34:47 -0300 Subject: [PATCH 18/28] Adding subsection on Size aspect for ordinary fixed-point types --- .../parts/data_types/numerics.rst | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index fb42af918..6e16a437d 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3431,6 +3431,30 @@ bits on the target platform |mdash| instead of the 32 bits that we would typically see for that type on a desktop PC. (As a reminder, this code example won't compile if your target architecture doesn't support 128-bit data types.) +Likewise, we can use the :ada:`Size` aspect with ordinary fixed-point types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Base_Type_Q47 + + with Ada.Text_IO; use Ada.Text_IO; + + procedure Show_Full_Range_Base_Type is + D : constant := 2.0 ** (-31); + + type Fixed_128_Bits is + delta D + range -1.0 .. 1.0 - D + with Size => 128; + begin + Put_Line ("The size of " + & "Fixed_128_Bits is " + & Fixed_128_Bits'Size'Image + & " bits"); + end Show_Full_Range_Base_Type; + +In this example, we require that :ada:`Fixed_128_Bits` has a size of 128 +bits on the target platform |mdash| instead of the 32 bits that we would +typically see for that type on a desktop PC. + .. _Adv_Ada_Fixed_Point_Machine_Representation: From 5886c8bd8a4b0e31a39e94bfc220a8cdd1079292 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:37:40 -0300 Subject: [PATCH 19/28] Adding subsection on machine representation of ordinary fixed-point types --- .../parts/data_types/numerics.rst | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 6e16a437d..5a94a5c3c 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3637,6 +3637,267 @@ For example, if we multiply the integer representation of the real value by the +-------------+-------------------------------+ +.. _Adv_Ada_Ordinary_Fixed_Point_Machine_Representation: + +Machine representation of ordinary fixed-point types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now let's look into how ordinary fixed-point types are typically represented in +actual hardware. Consider the types from the :ada:`Angles` package: + +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + + package Angles is + + D : constant := 0.2; + type Angle is + delta D + range 0.0 .. 360.0 - D; + + type Int_Angle is + range -2 ** (Angle'Size - 1) .. + 2 ** (Angle'Size - 1) - 1; + + type Angle_Adj is + delta D + range 0.0 .. 360.0 - D + with Small => D; + + type Int_Angle_Adj is + range -2 ** (Angle_Adj'Size - 1) .. + 2 ** (Angle_Adj'Size - 1) - 1; + + end Angles; + +As we've done before, we can use +:ref:`overlays ` to uncover the actual integer +values stored on the machine when assigning values to objects of fixed-point +type. We do this in the generic :ada:`Gen_Show_Info` procedure: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + :class: ada-run + + generic + type T_Fixed is delta <>; + type T_Int_Fixed is range <>; + procedure Gen_Show_Info (V : T_Fixed; + V_Str : String); + + with Ada.Text_IO; use Ada.Text_IO; + + procedure Gen_Show_Info (V : T_Fixed; + V_Str : String) + is + V_Local : T_Fixed; + + V_Int_Overlay : T_Int_Fixed + with Address => V_Local'Address, + Import, Volatile; + + V_Real : Float; + begin + V_Local := V; + V_Real := Float (V_Int_Overlay) * + T_Fixed'Small; + + Put_Line (V_Str + & " (fixed-point) : " + & Float (V_Local)'Image); + Put_Line (V_Str + & " (integer) : " + & V_Int_Overlay'Image); + Put_Line (V_Str + & " (floating-p.) : " + & V_Real'Image); + Put_Line ("----------"); + end Gen_Show_Info; + + with Gen_Show_Info; + + package Angles.Show_Info_Procs is + + procedure Show_Info is new + Gen_Show_Info (T_Fixed => Angle, + T_Int_Fixed => Int_Angle); + procedure Show_Info is new + Gen_Show_Info (T_Fixed => Angle_Adj, + T_Int_Fixed => Int_Angle_Adj); + + end Angles.Show_Info_Procs; + +With all these packages and procedures in place, let's write a test application +that displays a couple of values: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + :class: ada-run + + with Ada.Text_IO; use Ada.Text_IO; + + with Angles; use Angles; + + with Angles.Show_Info_Procs; + use Angles.Show_Info_Procs; + + procedure Show_Machine_Representation is + begin + Put_Line ("============================="); + Put_Line ("Angle"); + Put_Line ("============================="); + + Show_Info (Angle'First, "Angle'First "); + Show_Info (Angle'(0.25), "0.25 "); + Show_Info (Angle'(0.50), "0.50 "); + Show_Info (Angle'(0.75), "0.75 "); + Show_Info (Angle'(0.80), "0.80 "); + Show_Info (Angle'Last, "Angle'Last "); + + Put_Line ("============================="); + Put_Line ("Angle_Adj"); + Put_Line ("============================="); + + Show_Info (Angle_Adj'First, + "Angle_Adj'First "); + Show_Info (Angle_Adj'(0.25), + "0.25 "); + Show_Info (Angle_Adj'(0.50), + "0.50 "); + Show_Info (Angle_Adj'(0.75), + "0.75 "); + Show_Info (Angle_Adj'(0.80), + "0.80 "); + Show_Info (Angle_Adj'Last, + "Angle_Adj'Last "); + + end Show_Machine_Representation; + +The table below shows some of the values that we get by running the test +application: + ++-------------+---------------------------------+ +| Real value | Integer representation | +| +--------------+------------------+ +| | :ada:`Angle` | :ada:`Angle_Adj` | +| | type | type | ++=============+==============+==================+ +| 0.25 | 2 | 1 | ++-------------+--------------+------------------+ +| 0.50 | 4 | 2 | ++-------------+--------------+------------------+ +| 0.75 | 6 | 3 | ++-------------+--------------+------------------+ +| 0.80 | 6 | 4 | ++-------------+--------------+------------------+ + +Before we calculate the actual real value stored in the fixed-point objects, +we have to retrieve the *small* of these fixed-point types. The generic +:ada:`Gen_Show_Type_Info` procedure below provides us with some type +information: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + + generic + type T_Fixed is delta <>; + procedure Gen_Show_Type_Info + (Dummy : T_Fixed; + T_Fixed_Name : String); + + with Ada.Text_IO; use Ada.Text_IO; + + procedure Gen_Show_Type_Info + (Dummy : T_Fixed; + T_Fixed_Name : String) is + begin + Put_Line ("The size of " + & T_Fixed_Name + & " is " + & T_Fixed'Size'Image + & " bits"); + Put_Line ("The small of " + & T_Fixed_Name + & " is " + & T_Fixed'Small'Image); + Put_Line ("The delta value of " + & T_Fixed_Name + & " is " + & T_Fixed'Delta'Image); + Put_Line ("The minimum value of " + & T_Fixed_Name + & " is " + & T_Fixed'First'Image); + Put_Line ("The maximum value of " + & T_Fixed_Name + & " is " + & T_Fixed'Last'Image); + Put_Line ("-----------------------------"); + end Gen_Show_Type_Info; + +We instantiate the generic :ada:`Gen_Show_Type_Info` procedure for the +:ada:`Angle` and :ada:`Angle_Adj` types to retrieve the *small* of each type: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + :class: ada-run + + with Angles; use Angles; + + with Gen_Show_Type_Info; + + procedure Show_Machine_Representation is + procedure Show_Type_Info is new + Gen_Show_Type_Info (T_Fixed => Angle); + procedure Show_Type_Info is new + Gen_Show_Type_Info (T_Fixed => Angle_Adj); + begin + Show_Type_Info (Angle'(0.0), + "Angle "); + Show_Type_Info (Angle_Adj'(0.0), + "Angle_Adj "); + end Show_Machine_Representation; + +Now, for each value, we multiply the integer representation of that value by +the corresponding *small* of the type, so that we get the actual stored value. +These are the results for the :ada:`Angle` type |mdash| including the +difference between the original real value and the actual real value stored in +the fixed-point object: + ++-------------+------------------------------------------------------------+ +| Real value | :ada:`Angle` type | +| +---------------+-------------------------------+------------+ +| | Actual stored | Integer representation | Difference | +| | value | multiplied by the *small* | | ++=============+===============+===============================+============+ +| 0.25 | 0.25 | = 2 * 0.125 | 0 | ++-------------+---------------+-------------------------------+------------+ +| 0.50 | 0.50 | = 4 * 0.125 | 0 | ++-------------+---------------+-------------------------------+------------+ +| 0.75 | 0.75 | = 6 * 0.125 | 0 | ++-------------+---------------+-------------------------------+------------+ +| 0.80 | 0.75 | = 6 * 0.125 | 0.05 | ++-------------+---------------+-------------------------------+------------+ + +And these are the results for the :ada:`Angle_Adj` type: + ++-------------+------------------------------------------------------------+ +| Real value | :ada:`Angle_Adj` type | +| +---------------+-------------------------------+------------+ +| | Actual stored | Integer representation | Difference | +| | value | multiplied by the *small* | | ++=============+===============+===============================+============+ +| 0.25 | 0.2 | = 1 * 0.2 | 0.05 | ++-------------+---------------+-------------------------------+------------+ +| 0.50 | 0.4 | = 2 * 0.2 | 0.10 | ++-------------+---------------+-------------------------------+------------+ +| 0.75 | 0.6 | = 3 * 0.2 | 0.15 | ++-------------+---------------+-------------------------------+------------+ +| 0.80 | 0.8 | = 4 * 0.2 | 0 | ++-------------+---------------+-------------------------------+------------+ + +As we can see in the table, there might be numeric differences between the +values that we intend to store in the object and the values that actually +get stored there. These differences are directly related to the *small* +associated with the ordinary fixed-point type. In the end, the *small* defines +how accurate a given real value can be represented in the fixed-point object. + + .. _Adv_Ada_Fixed_Point_Types_Conversions: Type conversion using fixed-point types From 33ff087d8d621696754a110ccbe48f81512a8215 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:39:51 -0300 Subject: [PATCH 20/28] Adding subsection on conversion between ordinary fixed-point types --- .../parts/data_types/numerics.rst | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 5a94a5c3c..e79589776 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3958,6 +3958,218 @@ In this example, we convert the value of :ada:`D` |mdash| from the :ada:`Acc` by writing :ada:`Decimal (Acc)`, which converts it from the :ada:`Long_Long_Decimal` to the :ada:`Decimal` type. +Let's continue with the conversion between ordinary fixed-point types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Ordinary_Fixed_Type_Conversions + + package Custom_Fixed_Point is + D_15 : constant := 2.0 ** (-15); + D_31 : constant := 2.0 ** (-31); + + type TQ15 is + delta D_15 + range -1.0 .. 1.0 - D_15; + + type TQ31 is + delta D_31 + range -1.0 .. 1.0 - D_31; + + end Custom_Fixed_Point; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Fixed_Point_Conversions is + V_31 : TQ31; + V_15 : TQ15; + + procedure Show_Vars is + begin + Put_Line ("V_31 = " + & V_31'Image); + Put_Line ("V_15 = " + & V_15'Image); + Put_Line ("--------------"); + end Show_Vars; + begin + V_15 := 0.81182861328125; + V_31 := TQ31 (V_15); + Show_Vars; + + V_31 := 0.81182861328125; + V_15 := TQ15 (V_31); + Show_Vars; + end Show_Fixed_Point_Conversions; + +Here, we write :ada:`TQ31 (V_15)` to convert the value of :ada:`V_15` from the +:ada:`TQ15` to the :ada:`TQ31` type. Likewise, we write :ada:`TQ15 (V_31)` to +convert the value of :ada:`V_31` from the :ada:`TQ31` to the :ada:`TQ15` type. + +Finally, let's look into the conversion between ordinary and decimal +fixed-point types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Fixed_Type_Conversions + + package Custom_Fixed_Point is + + type Decimal is + delta 10.0 ** (-9) digits 9; + + D_31 : constant := 2.0 ** (-31); + type Fixed_Point is + delta D_31 + range -1.0 .. 1.0 - D_31; + + end Custom_Fixed_Point; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Fixed_Point_Conversions is + FP : Fixed_Point; + D : Decimal; + begin + FP := 0.5; + D := Decimal (FP); + + Put_Line ("FP = " + & FP'Image); + Put_Line ("D = " + & D'Image); + Put_Line ("------------------------------"); + + D := 0.25; + FP := Fixed_Point (D); + + Put_Line ("FP = " + & FP'Image); + Put_Line ("D = " + & D'Image); + end Show_Fixed_Point_Conversions; + +We see two conversions in the :ada:`Show_Fixed_Point_Conversions` procedure: +the conversion to a decimal type via :ada:`Decimal (FP)` and the conversion to +an ordinary fixed-point type via :ada:`Fixed_Point (D)`. + +.. admonition:: For further reading... + + Note that these two types aren't completely equivalent in terms of range or + size, but close enough for illustration. Let's look at the information for + each type: + + .. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Fixed_Type_Conversions + + package Fixed_Point_Type_Info is + + generic + type T_Fixed is delta <>; + procedure Gen_Show_Fixed_Type_Info + (Dummy : T_Fixed; + T_Fixed_Name : String); + + generic + type T_Decimal is delta <> digits <>; + procedure Gen_Show_Decimal_Type_Info + (Dummy : T_Decimal; + T_Decimal_Name : String); + + end Fixed_Point_Type_Info; + with Ada.Text_IO; use Ada.Text_IO; + + package body Fixed_Point_Type_Info is + + procedure Gen_Show_Fixed_Type_Info + (Dummy : T_Fixed; + T_Fixed_Name : String) is + begin + Put_Line ("The size of " + & T_Fixed_Name + & " is " + & T_Fixed'Size'Image + & " bits"); + Put_Line ("The small of " + & T_Fixed_Name + & " is " + & T_Fixed'Small'Image); + Put_Line ("The delta value of " + & T_Fixed_Name + & " is " + & T_Fixed'Delta'Image); + Put_Line ("The minimum value of " + & T_Fixed_Name + & " is " + & T_Fixed'First'Image); + Put_Line ("The maximum value of " + & T_Fixed_Name + & " is " + & T_Fixed'Last'Image); + Put_Line ("-----------------------------"); + end Gen_Show_Fixed_Type_Info; + + procedure Gen_Show_Decimal_Type_Info + (Dummy : T_Decimal; + T_Decimal_Name : String) is + begin + Put_Line ("The size of " + & T_Decimal_Name + & " is " + & T_Decimal'Size'Image + & " bits"); + Put_Line ("The small of " + & T_Decimal_Name + & " is " + & T_Decimal'Small'Image); + Put_Line ("The delta value of " + & T_Decimal_Name + & " is " + & T_Decimal'Delta'Image); + Put_Line ("The minimum value of " + & T_Decimal_Name + & " is " + & T_Decimal'First'Image); + Put_Line ("The maximum value of " + & T_Decimal_Name + & " is " + & T_Decimal'Last'Image); + Put_Line ("-----------------------------"); + end Gen_Show_Decimal_Type_Info; + + end Fixed_Point_Type_Info; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + with Fixed_Point_Type_Info; + use Fixed_Point_Type_Info; + + procedure Show_Fixed_Point_Conversions is + procedure Show_Type_Info is new + Gen_Show_Fixed_Type_Info + (T_Fixed => Fixed_Point); + + procedure Show_Type_Info is new + Gen_Show_Decimal_Type_Info + (T_Decimal => Decimal); + begin + Show_Type_Info (Decimal'(0.0), + "Decimal "); + Show_Type_Info (Fixed_Point'(0.0), + "Fixed_Point "); + end Show_Fixed_Point_Conversions; + + By running this test application, we see that the the size of + :ada:`Decimal` is 31 bits, while size of :ada:`Fixed_Point` is 32 bits. + Also, the *small* of :ada:`Decimal` is 1.0e-09 (10.0\ :sup:`-9`), while the + *small* of :ada:`Fixed_Point` is a bit smaller: 4.65661287307739258e-10 + (2.0\ :sup:`-31`). + In addition, the range of both types is very close, but not equivalent to + each other |mdash| from -0.999999999 to 0.999999999 for :ada:`Decimal` and + from -1.0 to 0.9999999995 for :ada:`Fixed_Point`. + .. _Adv_Ada_Fixed_Point_Type_Conversion_Other_Types: From 6a8c820a2ddfbb9e145c87afeb1762ac4710da52 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:41:42 -0300 Subject: [PATCH 21/28] Adding subsection on conversion from/to ordinary fixed-point and other types --- .../parts/data_types/numerics.rst | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index e79589776..c96fae37f 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4264,6 +4264,112 @@ type to a floating-point type |mdash| if we had assigned 2000.0 to :ada:`D6` instead of 800.0, for example, the conversion :ada:`TD18_1000 (D6)` would have raised a :ada:`Constraint_Error` because of the failed range check. +Similarly, we can convert from and to ordinary fixed-point types when using +other numeric types such as integer and floating-point types. For example: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Decimal_Type_Conversions_Other_Types + + package Custom_Types is + D_48 : constant := 2.0 ** (-48); + + type TQ15_48 is + delta D_48 + range -2.0 ** 15 .. + 2.0 ** 15 - D_48; + + type T2_D6 is + delta 10.0 ** (-2) digits 6; + -- Decimal type + + type TD18 is + digits 18; + -- Floating-point type + + type Int15 is + range -2 ** 15 .. + 2 ** 15; + -- Integer type + + end Custom_Types; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Types; + use Custom_Types; + + procedure Show_Decimal_Type_Conversions is + V_2_D6 : T2_D6; + V_D18 : TD18; + V_Q15_48 : TQ15_48; + V_Int15 : Int15; + begin + V_Q15_48 := 1.0; + + V_2_D6 := T2_D6 (V_Q15_48); + V_D18 := TD18 (V_Q15_48); + V_Int15 := Int15 (V_Q15_48); + -- ^^^^^^^^^^^^^^^^ + -- Conversions from + -- ordinary fixed-point + + Put_Line ("V_Q15_48 = " + & V_Q15_48'Image); + Put_Line ("V_2_D6 = " + & V_2_D6'Image); + Put_Line ("V_D18 = " + & V_D18'Image); + Put_Line ("V_Int15 = " + & V_Int15'Image); + Put_Line ("-----------------------------"); + + V_D18 := TD18 (TQ15_48'Last); + + V_Q15_48 := TQ15_48 (V_D18); + -- ^^^^^^^^^^^^^ + -- Conversion to + -- ordinary fixed-point + + Put_Line ("V_Q15_48 = " + & V_Q15_48'Image); + Put_Line ("V_D18 = " + & V_D18'Image); + Put_Line ("-----------------------------"); + + V_2_D6 := 2.0; + + V_Q15_48 := TQ15_48 (V_2_D6); + -- ^^^^^^^^^^^^^^^ + -- Conversion to + -- ordinary fixed-point + + Put_Line ("V_Q15_48 = " + & V_Q15_48'Image); + Put_Line ("V_2_D6 = " + & V_2_D6'Image); + Put_Line ("-----------------------------"); + + V_Int15 := 4; + + V_Q15_48 := TQ15_48 (V_Int15); + -- ^^^^^^^^^^^^^^^^^ + -- Conversion to + -- ordinary fixed-point + + Put_Line ("V_Q15_48 = " + & V_Q15_48'Image); + Put_Line ("V_Int15 = " + & V_Int15'Image); + Put_Line ("-----------------------------"); + + end Show_Decimal_Type_Conversions; + +In the :ada:`Custom_Types` package, we declare the ordinary fixed-point type +:ada:`TQ15_48`, the decimal type :ada:`T2_D6` and the floating-point type +:ada:`TD18`. We convert to the ordinary fixed-point type :ada:`TQ15_48` by +using :ada:`TQ15_48 (V_D18)`, :ada:`TQ15_48 (V_2_D6)`, or +:ada:`TQ15_48 (V_Int15)` for instance. We convert from the ordinary fixed-point +object :ada:`V_Q15_48` by writing :ada:`T2_D6 (V_Q15_48)`, +:ada:`TD18 (V_Q15_48)` or :ada:`Int15 (V_Q15_48)`. Operations using universal fixed types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 0cce3d4876ba23d2ec20515e67e6db46623d226f Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:45:05 -0300 Subject: [PATCH 22/28] Adding subsection on type conversions and machine representation --- .../parts/data_types/numerics.rst | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index c96fae37f..5868fc7d9 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4371,6 +4371,254 @@ using :ada:`TQ15_48 (V_D18)`, :ada:`TQ15_48 (V_2_D6)`, or object :ada:`V_Q15_48` by writing :ada:`T2_D6 (V_Q15_48)`, :ada:`TD18 (V_Q15_48)` or :ada:`Int15 (V_Q15_48)`. + +Type conversions and machine representation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's combine what we learned in the sections about +:ref:`type conversion of fixed-point types ` +and +:ref:`machine representation ` +and see the effect of type conversion to the machine representation of +fixed-point types. + + +.. _Adv_Ada_Decimal_Fixed_Point_Type_Conversion_Machine_Representation: + +Type conversions and machine representation of decimal types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To understand the machine representation of decimal types, let's reuse the +:ada:`T0_D4`, :ada:`T2_D6` and :ada:`T2_D12` types from the +:ada:`Custom_Decimal_Types` package. We can use the :ada:`Show_Info` procedure +we've created before to uncover the integer representation of the decimal +objects (:ada:`V_T0_D4`, :ada:`V_T2_D6` and :ada:`V_T2_D12`) after the type +conversion: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types + :class: ada-run + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Decimal_Types; + use Custom_Decimal_Types; + + with Custom_Decimal_Types.Show_Info_Procs; + use Custom_Decimal_Types.Show_Info_Procs; + + procedure Show_Machine_Representation is + V_T0_D4 : T0_D4; + V_T2_D6 : T2_D6; + V_T2_D12 : T2_D12; + begin + Put_Line ("============================="); + Put_Line ("T2_D6 <-- T0_D4"); + Put_Line ("============================="); + + Put_Line ("-----------------------------"); + Put_Line ("----- T0_D4 (152.0)"); + Put_Line ("-----------------------------"); + + V_T0_D4 := 152.0; + V_T2_D6 := T2_D6 (V_T0_D4); + + Show_Info (V_T0_D4, "V_T0_D4 "); + Show_Info (V_T2_D6, "V_T2_D6 "); + + Put_Line ("-----------------------------"); + Put_Line ("----- T0_D4 (1.0)"); + Put_Line ("-----------------------------"); + V_T0_D4 := 1.0; + V_T2_D6 := T2_D6 (V_T0_D4); + + Show_Info (V_T0_D4, "V_T0_D4 "); + Show_Info (V_T2_D6, "V_T2_D6 "); + + Put_Line ("============================="); + Put_Line ("T0_D4 <-- T2_D6"); + Put_Line ("============================="); + + Put_Line ("-----------------------------"); + Put_Line ("----- T2_D6 (225.0)"); + Put_Line ("-----------------------------"); + V_T2_D6 := 225.0; + V_T0_D4 := T0_D4 (V_T2_D6); + + Show_Info (V_T2_D6, "V_T2_D6 "); + Show_Info (V_T0_D4, "V_T0_D4 "); + + Put_Line ("-----------------------------"); + Put_Line ("----- T2_D6 (1.55)"); + Put_Line ("-----------------------------"); + V_T2_D6 := 1.55; + V_T0_D4 := T0_D4 (V_T2_D6); + + Show_Info (V_T2_D6, "V_T2_D6 "); + Show_Info (V_T0_D4, "V_T0_D4 "); + + Put_Line ("============================="); + Put_Line ("T2_D12 <-- T2_D6"); + Put_Line ("============================="); + + Put_Line ("-----------------------------"); + Put_Line ("----- T2_D6 (225.0)"); + Put_Line ("-----------------------------"); + V_T2_D6 := 225.0; + V_T2_D12 := T2_D12 (V_T2_D6); + + Show_Info (V_T2_D6, "V_T2_D6 "); + Show_Info (V_T2_D12, "V_T2_D12 "); + end Show_Machine_Representation; + +As we can see, the integer values are scaled to match the appropriate +representation required for each type. For instance, the value 152.0 is +represented as the integer value 152 for the :ada:`T0_D4` type. When converting +it to :ada:`T2_D6`, the integer value is scaled to that type, so it becomes +15200. The following table presents all values that show up when running the +test application: + ++--------+-----------------------------------+-----------------------------------+ +| Real | Original / source | Target | +| value +---------------+---------+---------+---------------+---------+---------+ +| | Type | Actual | Actual | Type | Actual | Actual | +| | | integer | real | | integer | real | +| | | value | value | | value | value | ++========+===============+=========+=========+===============+=========+=========+ +| 152.0 | :ada:`T0_D4` | 152 | 152.0 | :ada:`T2_D6` | 15200 | 152.0 | ++--------+---------------+---------+---------+---------------+---------+---------+ +| 1.0 | :ada:`T0_D4` | 1 | 1.0 | :ada:`T2_D6` | 100 | 1.0 | ++--------+---------------+---------+---------+---------------+---------+---------+ +| 225.00 | :ada:`T2_D6` | 22500 | 225.0 | :ada:`T0_D4` | 225 | 225.0 | ++--------+---------------+---------+---------+---------------+---------+---------+ +| 1.55 | :ada:`T2_D6` | 155 | 1.55 | :ada:`T0_D4` | 1 | 1.0 | ++--------+---------------+---------+---------+---------------+---------+---------+ +| 225.00 | :ada:`T2_D6` | 22500 | 225.0 | :ada:`T2_D12` | 22500 | 225.0 | ++--------+---------------+---------+---------+---------------+---------+---------+ + +As expected, when converting to a type with less accuracy |mdash| i.e. whose +*small* is greater than the *small* of the type we're converting from |mdash| +the integer representation might lose digits. For instance, when the value 1.55 +is converted from :ada:`T2_D6` type to the :ada:`T0_D4` type, the value becomes +1.00 |mdash| here, the corresponding integer representation 155 (for the +:ada:`T2_D6` type) is scaled down to 1 (for the :ada:`T0_D4` type). Naturally, +if we had converted this value back to original :ada:`T2_D6` type, the integer +representation would then be 100 instead of the previous 155. + +Also, when two types have the same *small*, the type conversion doesn't change +the machine representation. For example, when the value 225.0 is converted from +the :ada:`T2_D6` type to the :ada:`T2_D12` type, its integer representation +(22500) doesn't change, although these two types have different sizes and +different ranges. + + +.. _Adv_Ada_Ordinary_Fixed_Point_Type_Conversion_Machine_Representation: + +Type conversion and machine representation of ordinary fixed-point types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now, we discuss the machine representation of ordinary fixed-point types. For +that, let's reuse the :ada:`Angle` and :ada:`Angle_Adj` types from the +:ada:`Angles` package. Again, we use the :ada:`Show_Info` procedure we've +created before to uncover the integer representation of the fixed-point +objects (:ada:`V_Angle` and :ada:`V_Angle_Adj`) after the type conversion: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + :class: ada-run + + with Ada.Text_IO; use Ada.Text_IO; + + with Angles; use Angles; + + with Angles.Show_Info_Procs; + use Angles.Show_Info_Procs; + + procedure Show_Machine_Representation + is + V_Angle : Angle; + V_Angle_Adj : Angle_Adj; + begin + Put_Line ("============================="); + Put_Line ("Angle_Adj <-- Angle"); + Put_Line ("============================="); + + Put_Line ("-----------------------------"); + Put_Line ("----- Angle (90.0)"); + Put_Line ("-----------------------------"); + V_Angle := 90.0; + V_Angle_Adj := Angle_Adj (V_Angle); + + Show_Info (V_Angle, "V_Angle "); + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + + Put_Line ("-----------------------------"); + Put_Line ("----- Angle (0.5)"); + Put_Line ("-----------------------------"); + V_Angle := 0.5; + V_Angle_Adj := Angle_Adj (V_Angle); + + Show_Info (V_Angle, "V_Angle "); + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + + Put_Line ("============================="); + Put_Line ("Angle <-- Angle_Adj"); + Put_Line ("============================="); + + Put_Line ("-----------------------------"); + Put_Line ("----- Angle_Adj (95.0)"); + Put_Line ("-----------------------------"); + V_Angle_Adj := 95.0; + V_Angle := Angle (V_Angle_Adj); + + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + Show_Info (V_Angle, "V_Angle "); + + Put_Line ("-----------------------------"); + Put_Line ("----- Angle_Adj (0.5)"); + Put_Line ("-----------------------------"); + V_Angle_Adj := 0.5; + V_Angle := Angle (V_Angle_Adj); + + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + Show_Info (V_Angle, "V_Angle "); + end Show_Machine_Representation; + +As expected, the integer values are scaled to match the appropriate +representation for each type. For instance, the value 90.0 is represented as +the integer value 720 for the :ada:`Angle` type. When converting to +:ada:`Angle_Adj`, the integer value becomes 450. The following table presents +all values that show up when running the test application: + ++--------+----------------------------------------+----------------------------------------+ +| Real | Original / source | Target | +| value +--------------------+---------+---------+--------------------+---------+---------+ +| | Type | Actual | Actual | Type | Actual | Actual | +| | | integer | real | | integer | real | +| | | value | value | | value | value | ++========+====================+=========+=========+====================+=========+=========+ +| 90.0 | :ada:`Angle` | 720 | 90.0 | :ada:`Angle_Adj` | 450 | 90.0 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ +| 0.5 | :ada:`Angle` | 4 | 0.5 | :ada:`Angle_Adj` | 2 | 0.4 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ +| 95.0 | :ada:`Angle_Adj` | 475 | 95.0 | :ada:`Angle` | 760 | 95.0 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ +| 0.5 | :ada:`Angle_Adj` | 2 | 0.4 | :ada:`Angle` | 3 | 0.375 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ + +We've seen :ref:`before ` +that we might see inaccuracies for values close to the *small* of the ordinary +fixed-point type. Similarly, when converting to another fixed-point type, +further inaccuracies may be introduced. For example, the value 0.5 becomes 0.4 +when assigned it to an object of :ada:`Angle_Adj` type. When converting it to +the :ada:`Angle` type, the value becomes 0.375 |mdash| even though the original +value 0.5 could be perfectly represented with the :ada:`Angle` type. + +Note that, even though these inaccuracies become clear when we analyze +individual values to such a degree of detail, they're not restricted to +fixed-point types. In fact, inaccuracies might show up with floating-point +types as well because the mantissa of those types has a limited accuracy as +well. + + Operations using universal fixed types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 7b871339007244d7a5a4035e15ec7e568adda960 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:45:42 -0300 Subject: [PATCH 23/28] Editorial change: adding subsection title --- content/courses/advanced-ada/parts/data_types/numerics.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 5868fc7d9..01e5a9640 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4625,6 +4625,9 @@ Operations using universal fixed types Let's look at how fixed-point types behave in the case of operations that make use of :ref:`universal fixed types `. +Type conversions +^^^^^^^^^^^^^^^^ + When mixing objects of different fixed-point types, as usual, we can use :ref:`type conversions `, e.g. when assigning the result to an object of a different type. As we've mentioned From d355e0eb8fbf5dd2c6ec276632863552ea0a90d9 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:46:23 -0300 Subject: [PATCH 24/28] Editorial change: adding subsection title --- content/courses/advanced-ada/parts/data_types/numerics.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 01e5a9640..05c6dbf98 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4689,6 +4689,9 @@ fixed-point types. the code above, the :ada:`Short_Decimal (B)` would raise a :ada:`Constraint_Error` exception due the small difference in the range that we mentioned previously. +Multiplication and division operations with decimal types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + In addition, the multiplication and division operations also make use of universal fixed types. Consider the following package with decimal fixed-point types: From cd31c54f5712ccdf4b0f83be3887837331201a5d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:48:15 -0300 Subject: [PATCH 25/28] Adding subsection on multiplication/division and ordinary fixed-point types Adding subsection on multiplication/division and ordinary fixed-point types in the context of universal fixed types . --- .../parts/data_types/numerics.rst | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 05c6dbf98..e472a82ae 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4844,6 +4844,108 @@ types, and the :ada:`A / B` expression makes use of universal fixed types. universal fixed types, too.) +Multiplication and division operations with ordinary fixed-point types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now, let's see how ordinary fixed-point types also make use of universal +fixed types for multiplication and division operations. Consider the following +package: + +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Universal_Fixed + + package Custom_Fixed_Point is + D_15 : constant := 2.0 ** (-15); + D_24 : constant := 2.0 ** (-24); + D_31 : constant := 2.0 ** (-31); + + type TQ15 is + delta D_15 + range -1.0 .. 1.0 - D_15; + + type TQ31 is + delta D_31 + range -1.0 .. 1.0 - D_31; + + type TQ7_24 is + delta D_24 + range -2.0 ** 7 .. + 2.0 ** 7 - D_24; + + end Custom_Fixed_Point; + +The :ada:`Show_Universal_Fixed` procedure show a couple of multiplications +using universal fixed types: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Universal_Fixed + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Universal_Fixed is + Acc : TQ7_24; + A, B : TQ31; + begin + Acc := 1.0; + A := 0.75; + B := 0.75; + Put_Line ("A = " & A'Image); + Put_Line ("B = " & B'Image); + Put_Line ("Acc = " & Acc'Image); + Put_Line ("--------------"); + + Put_Line ("Acc := Acc * A * 2"); + Acc := Acc * A * 2; + -- ^^^^^^^^^^^ + -- Using universal fixed point + + Put_Line ("Acc = " & Acc'Image); + + Put_Line ("--------------"); + Put_Line ("A := Acc / 2 * B"); + A := Acc / 2 * B; + -- ^^^^^^^^^^^ + -- Using universal fixed point + Put_Line ("A = " & A'Image); + + end Show_Universal_Fixed; + +Because universal fixed types are used for the :ada:`Acc * A * 2` +or the :ada:`Acc / 2 * B` operation, we don't have to perform type conversion +before the multiplication, and the result of the operation has a meaningful +value. + +For the division operation, universal fixed types are used as well: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Ordinary_Fixed_Point_Types.Universal_Fixed + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Universal_Fixed is + Acc : TQ7_24; + A : TQ31; + begin + Acc := 1.0; + A := 0.75; + Put_Line ("A = " & A'Image); + Put_Line ("Acc = " & Acc'Image); + Put_Line ("--------------"); + + Put_Line ("Acc := Acc / A"); + Acc := Acc / A; + -- ^^^^^^^ + -- Using universal fixed point + + Put_Line ("Acc = " & Acc'Image); + end Show_Universal_Fixed; + +Here, the :ada:`Acc / A` operation makes use of universal fixed types. + + .. _Adv_Ada_Decimal_Fixed_Point_Types: Decimal fixed-point types From c7784f4c411ed6e65eea05a3c26a9a99604227f9 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:50:13 -0300 Subject: [PATCH 26/28] Adding subsection on integer multiplication and division --- .../parts/data_types/numerics.rst | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index e472a82ae..2da2f7fba 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4946,6 +4946,201 @@ For the division operation, universal fixed types are used as well: Here, the :ada:`Acc / A` operation makes use of universal fixed types. +.. _Adv_Ada_Fixed_Point_Integer_Multiplication_Division: + +Integer multiplication and division +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An interesting feature that exists for fixed-point types is the *direct* +multiplication or division by integers. This isn't possible with +floating-point types, though. For instance, if we have a fixed-point object +:ada:`A`, we can write a statement such as :ada:`A := A * 2;`. For a +floating-point object :ada:`F`, we would have to write :ada:`F := F * 2.0;`. +Similarly, if we had an object of integer type :ada:`I`, we could write +:ada:`A := A * I;` without having to convert :ada:`I` to the fixed-point type +of :ada:`A`. + +Let's look at the operations of the following code snippet: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Fixed_Integer_Multiplication_Division + + package Custom_Fixed_Point is + + type Decimal is + delta 10.0 ** (-9) digits 9; + + D_31 : constant := 2.0 ** (-31); + type Fixed_Point is + delta D_31 + range -1.0 .. 1.0 - D_31; + + end Custom_Fixed_Point; + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Fixed_Point; + use Custom_Fixed_Point; + + procedure Show_Fixed_Point_Integer_Mult_Div is + FP : Fixed_Point; + D : Decimal; + + procedure Show_Vars is + begin + Put_Line ("FP = " + & FP'Image); + Put_Line ("D = " + & D'Image); + Put_Line ("------------------------------"); + end Show_Vars; + + I : Integer := 8; + begin + FP := 0.25; + D := 0.25; + Show_Vars; + + FP := FP * 2; + D := D * 2; + Show_Vars; + + FP := FP / 4; + D := D / 4; + Show_Vars; + + FP := FP / I; + D := D / I; + Show_Vars; + end Show_Fixed_Point_Integer_Mult_Div; + +Because :ada:`FP` and :ada:`D` are fixed-point types, we can write :ada:`* 2`, +:ada:`/ 4` or :ada:`/ I` for objects of that type. + +If we look at the +:ref:`machine representation ` of +fixed-point types, it becomes clear that any integer operations we write for +objects of fixed-point types become integer operations on the corresponding +integer representation of those objects. In other words, in the *background*, +we're basically performing integer operations. + +Let's start with a code example for decimal types: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Decimal_Types + :class: ada-run + + with Ada.Text_IO; use Ada.Text_IO; + + with Custom_Decimal_Types; + use Custom_Decimal_Types; + + with Custom_Decimal_Types.Show_Info_Procs; + use Custom_Decimal_Types.Show_Info_Procs; + + procedure Show_Machine_Representation is + V_T0_D4 : T0_D4; + V_T2_D6 : T2_D6; + V_T2_D12 : T2_D12; + begin + Put_Line ("-----------------------------"); + Put_Line ("---- 152.0"); + Put_Line ("-----------------------------"); + + V_T0_D4 := 152.0; + V_T2_D6 := 152.0; + V_T2_D12 := 152.0; + + Show_Info (V_T0_D4, "V_T0_D4 "); + Show_Info (V_T2_D6, "V_T2_D6 "); + Show_Info (V_T2_D12, "V_T2_D12 "); + + Put_Line ("-----------------------------"); + Put_Line ("---- V := V * 2"); + Put_Line ("-----------------------------"); + + V_T0_D4 := V_T0_D4 * 2; + V_T2_D6 := V_T2_D6 * 2; + V_T2_D12 := V_T2_D12 * 2; + + Show_Info (V_T0_D4, "V_T0_D4 "); + Show_Info (V_T2_D6, "V_T2_D6 "); + Show_Info (V_T2_D12, "V_T2_D12 "); + end Show_Machine_Representation; + +The following table presents the values we get when we run the test +application: + ++--------+----------------------------------------+--------------------+-------------------+ +| Real | Original | Operation | Result | +| value +--------------------+---------+---------+ +---------+---------+ +| | Type | Actual | Actual | | Actual | Actual | +| | | integer | real | | integer | real | +| | | value | value | | value | value | ++========+====================+=========+=========+====================+=========+=========+ +| 152.0 | :ada:`T0_D4` | 152 | 152.0 | :ada:`V := V * 2` | 304 | 304.0 | ++--------+--------------------+---------+---------+ +---------+---------+ +| 152.0 | :ada:`T2_D6` | 15200 | 152.0 | | 30400 | 304.0 | ++--------+--------------------+---------+---------+ +---------+---------+ +| 152.0 | :ada:`T2_D12` | 15200 | 152.0 | | 30400 | 304.0 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ + +As we can see, the integer :ada:`* 2` operation is simply a multiplication by +two of the integer representation of the fixed-point objects. + +Now, let's look at an example for ordinary fixed-point types: + +.. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types + :class: ada-run + + with Ada.Text_IO; use Ada.Text_IO; + + with Angles; use Angles; + + with Angles.Show_Info_Procs; + use Angles.Show_Info_Procs; + + procedure Show_Machine_Representation + is + V_Angle : Angle; + V_Angle_Adj : Angle_Adj; + begin + Put_Line ("-----------------------------"); + Put_Line ("---- 90.0"); + Put_Line ("-----------------------------"); + + V_Angle := 90.0; + V_Angle_Adj := 90.0; + + Show_Info (V_Angle, "V_Angle "); + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + + Put_Line ("-----------------------------"); + Put_Line ("---- V := V * 2"); + Put_Line ("-----------------------------"); + V_Angle := V_Angle * 2; + V_Angle_Adj := V_Angle_Adj * 2; + + Show_Info (V_Angle, "V_Angle "); + Show_Info (V_Angle_Adj, "V_Angle_Adj "); + end Show_Machine_Representation; + +The table presents the values we get when we run the test application: + ++--------+----------------------------------------+--------------------+-------------------+ +| Real | Original | Operation | Result | +| value +--------------------+---------+---------+ +---------+---------+ +| | Type | Actual | Actual | | Actual | Actual | +| | | integer | real | | integer | real | +| | | value | value | | value | value | ++========+====================+=========+=========+====================+=========+=========+ +| 90.0 | :ada:`Angle` | 720 | 90.0 | :ada:`V := V * 2` | 1440 | 180.0 | ++--------+--------------------+---------+---------+ +---------+---------+ +| 90.0 | :ada:`Angle_Adj` | 450 | 90.0 | | 900 | 180.0 | ++--------+--------------------+---------+---------+--------------------+---------+---------+ + +Again, the integer :ada:`* 2` operation is simply a multiplication by two of +the integer representation of the fixed-point objects. + + .. _Adv_Ada_Decimal_Fixed_Point_Types: Decimal fixed-point types From 105aaf5ba1bf0d760eb44ef7e425997fef3732da Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 22:57:27 -0300 Subject: [PATCH 27/28] Editorial change: remove temporary block --- .../parts/data_types/numerics.rst | 54 ------------------- 1 file changed, 54 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index 2da2f7fba..d41ae0cba 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -4634,60 +4634,6 @@ when assigning the result to an object of a different type. As we've mentioned before, type conversions between fixed-point types make use of universal fixed-point types. -.. :: - - Consider the following package from a previous section: - - .. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Universal_Fixed_2 - - package Custom_Decimal_Types is - - type Short_Decimal is - delta 10.0 ** (-0) digits 4; - -- range -9_999.0 .. 9_999.0; - - type Decimal is - delta 10.0 ** (-2) digits 6; - -- range -9_999.99 .. 9_999.99; - - end Custom_Decimal_Types; - - Let's look at a simple example of type conversions between these types: - - .. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Universal_Fixed_2 - - with Ada.Text_IO; use Ada.Text_IO; - - with Custom_Decimal_Types; - use Custom_Decimal_Types; - - procedure Show_Mixing_Decimal_Types is - A : Short_Decimal; - B : Decimal; - begin - A := Short_Decimal'Last; -- 9_999.0 - B := Decimal (A); - Put_Line ("A = " & - A'Image); - Put_Line ("B = A = " & - B'Image); - - Put_Line ("--------------"); - B := 9_999.0; - A := Short_Decimal (B); - Put_Line ("B = " & - B'Image); - Put_Line ("A = B = " & - A'Image); - - end Show_Mixing_Decimal_Types; - - Here, we use :ada:`Decimal (A)` and :ada:`Short_Decimal (B)` to convert to :ada:`Decimal` - and :ada:`Short_Decimal`, respectively. - - Note that, if we had assigned :ada:`9_999.99` (or :ada:`Decimal`) to :ada:`B` in - the code above, the :ada:`Short_Decimal (B)` would raise a :ada:`Constraint_Error` - exception due the small difference in the range that we mentioned previously. Multiplication and division operations with decimal types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 96719a8399b97503330311b382e6a5e4b084425b Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sun, 15 Feb 2026 23:51:31 -0300 Subject: [PATCH 28/28] Editorial change: remove wrong class indicator in code block --- content/courses/advanced-ada/parts/data_types/numerics.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index d41ae0cba..1822f8bad 100644 --- a/content/courses/advanced-ada/parts/data_types/numerics.rst +++ b/content/courses/advanced-ada/parts/data_types/numerics.rst @@ -3675,7 +3675,6 @@ values stored on the machine when assigning values to objects of fixed-point type. We do this in the generic :ada:`Gen_Show_Info` procedure: .. code:: ada no_button project=Courses.Advanced_Ada.Data_Types.Numerics.Fixed_Point_Types.Machine_Representation_Ordinary_Fixed_Types - :class: ada-run generic type T_Fixed is delta <>;