In Ada 95 and later, yes, but for some reason Ada 95 wasn’t available in 1984.
Ah, I forgot that digits was 95 addition.
In (most, if not all) modern machines the scale of a fixed-point number is a construct in the mind of the programmer. What you have are plain old integers, and you might choose to interpret the LSB as having value 0.1 (1/10) say, or 0.0625 (1/16). If you multiply one of each together, you’ll get a (double-length) product where the LSB has value 1/160. Most of the pain of fixed-point multiplication is working out how you want to deal with that product; of division, how you want to present the dividend to the machine’s divide hardware to get the result you need.
But you cannot multiply values of two different fixed-point types anyway.
But in any case the point stands. If your scale is a power of the machine radix you can implement fixed-point multiplication and division using shifts in that radix.

But you cannot multiply values of two different fixed-point types anyway.
Oh yes you can. You “merely” have to deal with the scaling of the result.
with Ada.Text_IO; use Ada.Text_IO;
procedure Fixed is
type Dec is delta 0.1 range 0.0 .. 5.0 with
Small => 0.1;
type Fix is delta 0.1 range 0.0 .. 5.0;
Product_Delta : constant := Dec'Small * Fix'Small;
type Product is delta Product_Delta range 0.0 .. 25.0 with
Small => Product_Delta;
Half_Product_Delta : constant := Product_Delta / 2.0;
type Short_Product is delta Half_Product_Delta range 0.0 .. 25.0 with
Small => Half_Product_Delta;
D : Dec := 0.7;
F : Fix := 0.7;
begin
Put_Line (Product'(D * F)'Image);
Put_Line (Short_Product'(D * F)'Image);
end Fixed;
Both outputs are 0.481 (obviously should be 0.49, but it’s that F’(0.7)
).
But in any case the point stands. If your scale is a power of the machine radix you can implement fixed-point multiplication and division using shifts in that radix.
In the example I gave above, the compiler can generate the Product
result by taking the unaltered output of the multiplication. To generate the Half_Product
result it would have to shift the output up one place. If you decided to assign the result to a type with a ’Small
that wasn’t a binary multiple, say Product_Delta / 3.0
, the compiler would have to scale the result to match (in that case, multiplying the multiplication’s output by 3).

Oh yes you can. You “merely” have to deal with the scaling of the result.
OK, I get universal_fixed which is a rational number.
Compare code generated for decimal and binary fixed-point:
type Dec is delta 0.1 digits 2 range 0.0 .. 5.0;
type Fix is delta 0.1 range 0.0 .. 5.0;
D : Dec := 0.7;
F : Fix := 0.7;
begin
D := D * D;
F := F * F;
You need a lot more for the decimal one because the machine radix is 2.