On Sat, Jul 27, 2024 at 05:25:52PM +0200, Grégory Vanuxem wrote:
> No. toString(3.7,20)
> 
> Le sam. 27 juil. 2024 à 17:24, Waldek Hebisch <[email protected]> a écrit :
> >
> > On Sat, Jul 27, 2024 at 03:31:57PM +0200, Grégory Vanuxem wrote:
> > > =>
> > > (1)  "4.30000000000000000000"
> > >
> > > I wanted to use it, but apparently not now ;)

AFAICS the attached patch fixes the problem for Float.  To handle
DoubleFloat we probably should move floating point formatting to
a separate package and use approptiate routine from this package
also for DoubleFloat.  In fact, I would prefer to do _all_
DoubleFloat formatting via such a package (so get rid of Lisp
formatting).

-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/ZrAnAxhlBl_NEtZd%40fricas.org.
--- ../fr-build132/src/algebra/FLOAT.spad	2024-07-09 22:06:26.345296444 +0000
+++ FLOAT.spad	2024-08-05 00:41:12.245541183 +0000
@@ -795,6 +795,8 @@
    zero ==> char("0")
    separator ==> underscore()$Character
 
+   mode_Rec ==> Record(out_prec : I, out_mode : S, spacing : I)
+
    SPACING : N := 10
    OUTMODE : S := "general"
    OUTPREC : I := -1
@@ -803,47 +805,51 @@
    floating : % -> S
    general : % -> S
 
-   padFromLeft(s : S) : S ==
-      zero? SPACING => s
+   padFromLeft(s : S, mr : mode_Rec) : S ==
+      sp := mr.spacing
+      zero?(sp) => s
       n : I := #s - 1
-      t := new( (n + 1 + n quo SPACING) :: N , separator )
+      t := new((n + 1 + n quo sp)::N, separator)
       for i in 0..n for j in minIndex t .. repeat
          t.j := s.(i + minIndex s)
-         if (i+1) rem SPACING = 0 then j := j+1
+         if (i + 1) rem sp = 0 then j := j + 1
       t
-   padFromRight(s : S) : S ==
-      SPACING = 0 => s
+
+   padFromRight(s : S, mr : mode_Rec) : S ==
+      sp := mr.spacing
+      zero?(sp) => s
       n : I := #s - 1
-      t := new( (n + 1 + n quo SPACING) :: N , separator )
+      t := new((n + 1 + n quo sp)::N, separator)
       for i in n..0 by -1 for j in maxIndex t .. by -1 repeat
          t.j := s.(i + minIndex s)
-         if (n-i+1) rem SPACING = 0 then j := j-1
+         if (n - i + 1) rem sp = 0 then j := j - 1
       t
 
-   fixed f ==
-      d := if OUTPREC = -1 then digits()::I else OUTPREC
+   fixed_mr(f : %, mr : mode_Rec) : S ==
+      nn := mr.out_prec
+      d := if nn = -1 then digits()::I else nn
       zero? f =>
-         OUTPREC = -1 => "0.0"
-         concat("0", concat(".", padFromLeft new(d::N, zero)))
+         nn = -1 => "0.0"
+         concat("0", concat(".", padFromLeft(new(d::N, zero), mr)))
       zero? exponent f =>
-        concat(padFromRight convert(mantissa f)@S,
-               concat(".", padFromLeft new(d::N, zero)))
-      negative? f => concat("-", fixed abs f)
+        concat(padFromRight(convert(mantissa f)@S, mr),
+               concat(".", padFromLeft(new(d::N, zero), mr)))
+      negative? f => concat("-", fixed_mr([-f.mantissa, f.exponent], mr))
       bl := LENGTH(f.mantissa) + f.exponent
       dd :=
-          OUTPREC = -1 => d
+          nn = -1 => d
           bl > 0 => (146*bl) quo 485 + 1 + d
           d
-      g := convert10(abs f, dd)
+      g := convert10(f, dd)
       m := g.mantissa; e := g.exponent
-      if OUTPREC ~= -1 then
-         -- round g to OUTPREC digits after the decimal point
+      if nn ~= -1 then
+         -- round g to nn digits after the decimal point
          l := length10 m
-         if -e > OUTPREC and -e < 2*digits()::I then
-            g := normalize10(g, l+e+OUTPREC)
+         if -e > nn and -e < 2*digits()::I then
+            g := normalize10(g, l + e + nn)
             m := g.mantissa; e := g.exponent
       s := convert(m)@S; n := #s; o := e+n
-      p := if OUTPREC = -1 then n::I else OUTPREC
+      p := if nn = -1 then n::I else nn
       t : S
       if e >= 0 then
          s := concat(s, new(e::N, zero))
@@ -855,39 +861,45 @@
          t := s(o + minIndex s .. n + minIndex s - 1)
          s := s(minIndex s .. o + minIndex s - 1)
       n := #t
-      if OUTPREC = -1 then
+      if nn = -1 then
          t := rightTrim(t, zero)
          if t = "" then t := "0"
       else if n > p then t := t(minIndex t .. p + minIndex t- 1)
                     else t := concat(t, new((p-n)::N, zero))
-      concat(padFromRight s, concat(".", padFromLeft t))
+      concat(padFromRight(s, mr), concat(".", padFromLeft(t, mr)))
+
+   fixed(f : %) : S == fixed_mr(f, [OUTPREC, OUTMODE, SPACING])
+
+   toString(f : %, n : N) : S == fixed_mr(f, [n, "fixed", 0])
 
-   floating f ==
+   floating_mr(f : %, mr : mode_Rec) : S ==
       zero? f => "0.0"
-      negative? f => concat("-", floating abs f)
-      t:S := if zero? SPACING then "E" else " E "
+      negative? f => concat("-", floating_mr([-f.mantissa, f.exponent], mr))
+      t : S := if zero?(mr.spacing) then "E" else " E "
       zero? exponent f =>
-        s := convert(mantissa f)@S
-        concat ["0.", padFromLeft s, t, convert(#s)@S]
+          s := convert(mantissa f)@S
+          concat(["0.", padFromLeft(s, mr), t, convert(#s)@S])
       -- base conversion to decimal rounded to the requested precision
-      d := if OUTPREC = -1 then digits()::I else OUTPREC
+      d := if mr.out_prec = -1 then digits()::I else mr.out_prec
       g := convert10(f, d); m := g.mantissa; e := g.exponent
       -- I'm assuming that length10 m = # s given n > 0
       s := convert(m)@S; n := #s; o := e+n
-      s := padFromLeft s
+      s := padFromLeft(s, mr)
       concat ["0.", s, t, convert(o)@S]
 
-   general(f) ==
+   floating(f : %) : S == floating_mr(f, [OUTPREC, OUTMODE, SPACING])
+
+   general_mr(f : %, mr : mode_Rec) : S ==
       zero? f => "0.0"
-      negative? f => concat("-", general abs f)
-      d := if OUTPREC = -1 then digits()::I else OUTPREC
+      negative? f => concat("-", general_mr([-f.mantissa, f.exponent], mr))
+      d := if mr.out_prec = -1 then digits()::I else mr.out_prec
       zero? exponent f =>
         d := d + 1
         s := convert(mantissa f)@S
-        OUTPREC ~= -1 and (e := #s) > d =>
-          t:S := if zero? SPACING then "E" else " E "
-          concat ["0.", padFromLeft s, t, convert(e)@S]
-        concat(padFromRight(s), ".0")
+        mr.out_prec ~= -1 and (e := #s) > d =>
+            t : S := if zero?(mr.spacing) then "E" else " E "
+            concat(["0.", padFromLeft(s, mr), t, convert(e)@S])
+        concat(padFromRight(s, mr), ".0")
       -- base conversion to decimal rounded to the requested precision
       g := convert10(f, d); m := g.mantissa; e := g.exponent
       -- I'm assuming that length10 m = # s given n > 0
@@ -898,17 +910,20 @@
          -- fixed format: add trailing zeroes before the decimal point
          if o > n then s := concat(s, new((o-n)::N, zero))
          t := rightTrim(s(o + minIndex s .. n + minIndex s - 1), zero)
-         if t = "" then t := "0" else t := padFromLeft t
-         s := padFromRight s(minIndex s .. o + minIndex s - 1)
+         if t = "" then t := "0" else t := padFromLeft(t, mr)
+         s := padFromRight(s(minIndex s .. o + minIndex s - 1), mr)
          concat(s, concat(".", t))
       else if o <= 0 and o >= -5 then
-         -- fixed format: up to 5 leading zeroes after the decimal point
-         concat("0.",padFromLeft concat(new((-o)::N,zero),rightTrim(s,zero)))
+          -- fixed format: up to 5 leading zeroes after the decimal point
+          concat("0.", padFromLeft(concat(new((-o)::N, zero),
+                                        rightTrim(s, zero)), mr))
       else
-         -- print using E format written  0.mantissa E exponent
-         t := padFromLeft rightTrim(s, zero)
-         s := if zero? SPACING then "E" else " E "
-         concat ["0.", t, s, convert(e+n)@S]
+          -- print using E format written  0.mantissa E exponent
+          t := padFromLeft(rightTrim(s, zero), mr)
+          s := if zero?(mr.spacing) then "E" else " E "
+          concat(["0.", t, s, convert(e + n)@S])
+
+   general(f : %) : S == general_mr(f, [OUTPREC, OUTMODE, SPACING])
 
    outputSpacing n ==
        old_val := SPACING

Reply via email to