Skip to content

Commit 81bce77

Browse files
committed
Adding admonition about custom * and / operators
1 parent de5ee7f commit 81bce77

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

content/courses/advanced-ada/parts/data_types/numerics.rst

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,105 @@ by a variable of type :ada:`T3_D3`, and assigning it to a variable of type
964964
conversions because the underlying types for the fixed-point division operation
965965
are universal fixed types.
966966

967+
.. admonition:: For further reading...
968+
969+
It's possible to implement custom :ada:`*` and :ada:`/` operators for
970+
fixed-point types. However, those operators do **not** override the
971+
corresponding operators for universal fixed-point types. For example:
972+
973+
.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Types.Universal_Types.Fixed_Point_Custom_Multiplication
974+
975+
package Normalized_Fixed_Point_Types is
976+
977+
type TQ63 is
978+
delta 2.0 ** (-63)
979+
range -1.0 .. 1.0 - 2.0 ** (-63);
980+
981+
type TQ31 is
982+
delta 2.0 ** (-31)
983+
range -1.0 .. 1.0 - 2.0 ** (-31);
984+
985+
overriding
986+
-- ^^^^^^
987+
-- "+" operator is overriding!
988+
function "+" (L, R: TQ31)
989+
return TQ31;
990+
991+
not overriding
992+
-- ^^^^^^^^^^
993+
-- "*" operator is NOT overriding!
994+
function "*" (L, R: TQ31)
995+
return TQ31;
996+
997+
type TQ15 is
998+
delta 2.0 ** (-15)
999+
range -1.0 .. 1.0 - 2.0 ** (-15);
1000+
1001+
end Normalized_Fixed_Point_Types;
1002+
1003+
with Ada.Text_IO; use Ada.Text_IO;
1004+
1005+
package body Normalized_Fixed_Point_Types is
1006+
1007+
function "+" (L, R: TQ31)
1008+
return TQ31 is
1009+
begin
1010+
Put_Line ("Using the overriding ´+' operator");
1011+
return TQ31 (TQ63 (L) + TQ63 (R));
1012+
end "+";
1013+
1014+
function "*" (L, R: TQ31)
1015+
return TQ31 is
1016+
begin
1017+
Put_Line ("Using the non-overriding ´*' operator");
1018+
return TQ31 (TQ63 (L) * TQ63 (R));
1019+
end "*";
1020+
1021+
end Normalized_Fixed_Point_Types;
1022+
1023+
with Ada.Text_IO; use Ada.Text_IO;
1024+
1025+
with Normalized_Fixed_Point_Types;
1026+
use Normalized_Fixed_Point_Types;
1027+
1028+
procedure Show_Fixed_Multiplication is
1029+
Q31_A : TQ31 := 0.25;
1030+
Q31_B : TQ31 := 0.50;
1031+
Q15_A : TQ15 := 0.25;
1032+
Q15_B : TQ15 := 0.50;
1033+
begin
1034+
Q31_A := Q31_A * Q31_B;
1035+
Put_Line ("Q31_A = " & Q31_A'Image);
1036+
1037+
Q15_A := Q15_A * Q15_B;
1038+
Put_Line ("Q15_A = " & Q31_A'Image);
1039+
1040+
Q15_A := TQ15 (Q31_A) * Q15_B;
1041+
-- ^^^^^^^^^^^^
1042+
-- A conversion is required because of
1043+
-- the multiplication operator of
1044+
-- TQ15.
1045+
Put_Line ("Q31_A = " & Q31_A'Image);
1046+
end Show_Fixed_Multiplication;
1047+
1048+
In this example, we're declaring a custom multiplication operator for the
1049+
:ada:`TQ31` type. As we can see in the declaration, we specify that it's
1050+
:ada:`not overriding` the :ada:`*` operator. (Removing the :ada:`not`
1051+
keyword triggers a compilation error.) In contrast, for the :ada:`+`
1052+
operator, we're indeed overriding the default :ada:`+` operator of the
1053+
:ada:`TQ31` type in the :ada:`Normalized_Fixed_Point_Types` because the
1054+
addition operator is associate with its corresponding fixed-point type,
1055+
not with the universal fixed-point type. In the
1056+
:ada:`Q31_A := Q31_A * Q31_B` statement, we see at runtime (through the
1057+
"Using the non-overriding ´*' operator" message) that the custom
1058+
multiplication is being used.
1059+
1060+
However, because of this custom :ada:`*` operator, we cannot mix objects of
1061+
this type with objects of other fixed-point types in multiplication or
1062+
division operations. Therefore, for a statement such as
1063+
:ada:`Q15_A := Q31_A * Q15_B`, we have to convert :ada:`Q31_A` to the
1064+
:ada:`TQ15` type before multiplying it by :ada:`Q15_B`.
1065+
9671066
.. admonition:: In the Ada Reference Manual
9681067

9691068
- :arm22:`4.5.5 Multiplying Operators <4-5-5>`

0 commit comments

Comments
 (0)