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