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