diff --git a/content/courses/advanced-ada/parts/data_types/numerics.rst b/content/courses/advanced-ada/parts/data_types/numerics.rst index c7cbd2b24..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... @@ -3374,10 +3374,10 @@ 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_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 @@ -3394,13 +3394,76 @@ 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; -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: +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_Implementation_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 <>; + 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; + +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_Representation_Decimal_Types :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -3408,64 +3471,30 @@ 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_Representation 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 ("-----------------------------"); - 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: + 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 "); + Show_Info (T2_D6'(2.0), "2.0 "); + end Show_Machine_Representation; + +The table shows the values that we get by running the test application: +-------------+-----------------------------+ | Real value | Integer representation | @@ -3492,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: +-------------+-------------------------------+