Problem? with float()

chris hermansen clhermansen@gmail.com
Wed Mar 11 22:01:21 GMT 2026


Hello again,

On Wed, Mar 11, 2026 at 1:25 PM Jose E. Marchesi <jemarch@gnu.org> wrote:

>
> > Hello everyone,
> >
> > I am having a problem printing anything beyond one or more asterisks with
> > the float proc.
> >
> > At first I thought it was just my inexperience / ignorance, so I tried
> some
> > examples from McGettrick:
> >
> > begin
> >   puts(float(123.4567,12,5,2));
> >   puts("'n");
> >   puts(float(123.4567,-10,5,-1));
> >   puts("'n");
> >
> >   skip
> > end
> >
> > He suggests this should produce
> >
> > +12.34567e+1
> >  1.23457e2 (blank just in front)
> >
> > Am I missing something?  Thanks in advance!
>
>
> Hm, perhaps I got the proc wrong from the RR.  This is what we have
> right now in the standard prelude (libga68/standard.a68.in):
>
>     pub proc float = (Number v, int width, after, exp) string:
>         case v in
>            {iter L  {} {long}  {long long}}
>            {iter L_ {} {long_} {long_long_}}
>            ({L} real x):
>               if int before = ABS width - ABS exp - (after /= 0 | after+1
> | 0) - 2;
>                  SIGN before + SIGN after > 0
>               then string s, {L} real y := ABS x, int p := 0;
>                    {L_}standardize (y, before, after, p);
>                    s := fixed (SIGN (x * y), SIGN width * (ABS width - ABS
> exp - 1),
>                                after) + "*^" + whole (p, exp);
>                    if exp = 0 OR char_in_string (errorchar, loc int, s)
>                    then float (x, width, (after /= 0 | after-1 | 0),
>                                (exp > 0 | exp+1 | exp-1))
>                    else s
>                    fi
>               else { XXX undefined } skip; ABS width * errorchar
>               fi,
>            ({L} int x): float ({L} real (x), width, after, exp)
>            {reti {,}}
>         esac;
>

A couple of things bother me above:

I  think there's something wrong with using the same {iter L ...} to
encapsulate both real and int real parameters.  That is, I think the part:

           ({L} int x): float ({L} real (x), width, after, exp)
           {reti {,}}

should be wrapped separately

{iter L {short short} {short} {} {long} {long long}}
{iter R {LENG LENG} {LENG} {} {} {}}
           ({L} int x): float ({R} real (x), width, after, exp)
           {reti {,}}
{reti {,}}

or similar.

Besides that, you have SIGN (x * y) and I think it should be SIGN x * y; at
least, that's how it's presented in the RR.


> The idea was to replace it with van Vliet's:
>
> PROC float = (NUMBER v, INT width, after, exp) STRING:
>   IF INT abs width = ABS width, sign after = SIGN after,
>     INT exp places:= ABS exp;
>     INT last:= abs width - exp places - 2;
>     INT before:= last - after - sign after;
>     SIGN before + sign after <= 0
>       # partial test for correctness of parameters #
>   THEN 1 MAX abs width * errorchar
>   ELIF INT first:= 1, exponent:= before, rp:= last + 1;
>     [-1 : abs width - sign after] CHAR s, BOOL exp sign = exp > 0;
>     BOOL neg:= subfixed(v, after, exponent, s, TRUE);
>       # 's[1 : before + after + 2]' contains the relevant
>         digits, 's[before + 1]' = "." #
>     exponent -:= before;
>       # now 'exponent' is the real exponent #
>     WHILE
>       IF rp > last
>       THEN
>         IF power10(s, rp, last)
>         THEN first:= 0; s[before]:= ".";
>           s[before + 1]:= (before = 0 | rp:= 1; "0" | "9");
>           before -:= 1; last -:= 1; exponent +:= 1
>         FI
>           # move the decimal point one place
>             to the left and adjust the various parameters #
>       FI;
>       exp sign EXPLENGTH exponent > exp places AND last >= first
>         # the exponent does not fit and it is
>           still possible to sacrifice digits #
>     DO last -:= 1; exp places +:= 1;
>       CASE SIGN(last - before - 1) + 2
>       IN
>         (before -:= 1; exponent +:= 1),
>           # "after" = 0, so decrement 'before' #
>         (before +:= 1; exponent -:= 1;
>          REF CHAR sb1 = s[before + 1]; s[before]:= sb1; sb1:= ".")
>           # "after":= 0, so the decimal point also disappears;
>             as a consequence, 'before' can be incremented #
>     # OUT "after" is decremented, but still greater than 0 #
>       ESAC
>     OD;
>     last < first   # no digits left in mantissa #
>   THEN abs width * errorchar
>   ELSE round(s, rp, last);
>     INT p:= first;
>     WHILE s[p] = "0" AND s[p + 1] /= "." AND p < last
>     DO s[p]:= " "; p +:= 1 OD;
>       # change "000.00" to "  0.00" #
>     s[p - 1]:= (neg | "-" |: width > 0 | "+" | " ");
>     s[last +:= 1]:= "e"; INT l = last + exp places;
>       # convert exponent into 's[last + 1 : l]': #
>     neg:= subwhole(exponent, last +:= 1, l, s);
>     (neg OR exp sign | s[last - 1]:= (neg | "-" | "+"));
>       # place sign of exponent #
>     s[first - 1 : l]
>   FI;
>


-- 
Chris Hermansen · clhermansen "at" gmail "dot" com

C'est ma façon de parler.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/algol68/attachments/20260311/bafe4f11/attachment-0001.htm>


More information about the Algol68 mailing list