Request for comment: a few extensions to the standard prelude for real numbers

Jose E. Marchesi jemarch@gnu.org
Thu Dec 11 13:19:54 GMT 2025


Hi Chris.

> Hello all,
>
> In another email thread, I commented that it would be useful to have
> something like BIN defined for real to bits conversion and ABS for bits to
> real.  Jose kindly suggested that I prepare a proposal to include this as a
> GNU extension to the standard prelude.
>
> After some thought, I decided to propose two mechanisms that have the same
> objective, which is to facilitate converting binary real numbers to string
> representations of decimal fixed or floating point and vice versa.
>
> Note below I'm using Ľ (capital L with caron) for SIZETY and # for the
> comment symbol.
>
> The first mechanism is a set of three "getter" operators:
>
> op sign = (Ľ real a) int: (a > Ľ 0 | 1 |: a < Ľ 0 | -1 | 0) # this is
> defined similarly to sign for integers #;
> op significand = (Ľ real a) Ľ int: # return the significand of the Ľ real
> value a as an integer #;
> op exponent = (Ľ real a) int: # return the significand of the Ľ real value
> a as an integer #;
>
> and three "setter" operators:
>
> op sign = (Ľ real a, int s) Ľ real: # return an Ľ real value the same as a
> but with the sign set to positive if s is greater than or equal to 0,
> negative if s is less than 0 #;
> op significand = (Ľ real a, Ľ int s) Ľ int: # return an Ľ real value the
> same as a but with the significand set to Ľ int s #;
> op exponent = (Ľ real a, int e) Ľ int: # return an Ľ real value the same as
> a but with the exponent set to int e #;
>
> These three "setter" operators could of course be combined into one
> procedure, something like:
>
> proc to real = (int sign, int exponent, Ľ int significand) Ľ real: # return
> a Ľ real given int sign, int exponent and Ľ int significand #;
>
> and of course the "getter" operators could be combined into one procedure,
> something like:
>
> proc from real = (ref int sign, ref int exponent, ref Ľ real significand, Ľ
> real a) void: # extract sign, exponent and significand from Ľ real a
> #;

What about having:

  mode RealRepr = struct (bool si, int ex, ma);

  op ABS = (RealRepr rr) real: skip,
     REPR = (real r) RealRepr: skip;

This would allow using row displays in strong contexts and casts in
other contexts such as:

  ABS (true, 1, 100)
  ABS (false, 1, 100)
  REPR -3.14

Using REPR here is of questionable taste but I think it is best in
general to use standard operation names rather than introducing new
ones..

>
> I can see pros and cons to each approach above, but in both cases I think
> the mechanism provides clarity of intent and leaves the knowledge of the
> hardware representation details to the writer of the operators or
> procedures, and would therefore encourage portability among floating point
> representations.  It lacks obvious means to deal with edge cases such as
> not-a-number, infinity and subnormal numbers; however these could be
> provided as a separate set of operators such as:
>
> op is infinite (Ľ real a) bool: # return true if the value of Ľ real a
> corresponds to hardware infinity #;
> op is nan (Ľ real a) bool: # return true if the value of Ľ real a
> corresponds to hardware not-a-number #;
> op is subnormal (Ľ real a) bool: # return true if the value of Ľ real a
> corresponds to hardware subnormal #;
>
> Another lacking is knowing the maximum sizes of the exponent and
> significand; this could be dealt with via environment queries in the
> standard prelude, indicating for example the number of bits in exponent and
> significand.
>
> The second mechanism surfaces knowledge of the representation and structure
> of floating point numbers, most probably following the IEEE 754 standard.
>
> In this case, we would define the operators:
>
> op bin = (Ľ real a) Ľ bits: # return the Ľ bit pattern of the Ľ real number
> a #;
> op abs = (Ľ bits a) Ľ real: # put the Ľ real number corresponding to the Ľ
> bits pattern a #;
>
> which are analogous to those defined for Ľ int values (I believe we would
> have to choose a name other than "abs" for the bits to real transformation
> in order not to conflict with the abs that takes Ľ bits and returns Ľ int).
>
> This allows (forces) us to confront the hardware representation directly in
> the use of the conversion routines.  I see this as less desirable than the
> first mechanism because we could end up with hardware representation
> details scattered around other bits of code, meaning the likely first thing
> that would be done with this new conversion pair would be to wrap them in
> the operators (or procedures) described in the first mechanism.
>
> Therefore, my preference would be to implement the first mechanism as a way
> to have efficient conversion from external to internal representation and
> vice versa.
>
> Any and all comments welcomed!


More information about the Algol68 mailing list