Problem? with float()

Jose E. Marchesi jemarch@gnu.org
Wed Mar 11 20:25:00 GMT 2026


> 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;

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;


More information about the Algol68 mailing list