Re: text.e bugs?
- Posted by cargoan Jan 24, 2015
- 2210 views
irv said...
Just downloaded and compiled. Only one question remains, should text:format round in the same manner as printf, or is this better left as an option for the programmer?
7 Printf: 1499.46 Fmt A: 1,499.45 Fmt B: 1,499.45 Raw: 1499.459 8 Printf: -267.46 Fmt A: (267.45) Fmt B: -267.45 Raw: -267.456
Something like that? (adding 'r' to decs):
[$]: cat ~/pru2.ex; eui ~/pru2.ex
include std/text.e
puts(1, format("Fmt A: [(,,:12.2] Fmt B: [,,:12.2] Raw: []\n", {-267.456,-267.456,-267.456}))
puts(1, format("Fmt A: [(,,:12.2r] Fmt B: [,,:12.2r] Raw: []\n", {-267.456,-267.456,-267.456}))
puts(1, format("Fmt A: [(,,:12.] Fmt B: [,,:12.] Raw: []\n", {-267.56,-267.56,-267.56}))
puts(1, format("Fmt A: [(,,:12.] Fmt B: [,,:12.r] Raw: []\n", {-267.56,-267.56,-267.56}))
puts(1, format("The answer is [.4]\n", {1.234567e17}))
puts(1, format("The answer is [.4r]\n", {1.234567e17}))
puts(1, format("The answer is [.]\n", {1.567234e17}))
puts(1, format("The answer is [.r]\n", {1.567234e17}))
Fmt A: (267.45) Fmt B: -267.45 Raw: -267.456
Fmt A: (267.46) Fmt B: -267.46 Raw: -267.456
Fmt A: (267) Fmt B: -267 Raw: -267.56
Fmt A: (267) Fmt B: -268 Raw: -267.56
The answer is 1.2345e+17
The answer is 1.2346e+17
The answer is 1e+17
The answer is 2e+17
with this patch:
--- text.e 2015-01-26 09:35:20.466148000 +0100
+++ text.e 2015-01-26 09:22:46.022148000 +0100
@@ -1412,18 +1412,16 @@
ifdef BITS64 then
constant MAX_BITS = 64
constant MAX_DIGS = 18
- constant MAX_INT = 0x3FFF_FFFF_FFFF_FFFF
- constant MIN_INT = -0x4000_0000_0000_0000
elsedef
constant MAX_BITS = 32
constant MAX_DIGS = 15
- constant MAX_INT = 0x3FFF_FFFF
- constant MIN_INT = -0x4000_0000
end ifdef
constant MAX_UCS4 = 0xFFFF_FFFF
constant MAX_IFMT = 0x3FFF_FFFF
constant MIN_IFMT = -0x4000_0000
+constant MAX_FFMT = power(10, 15)
+constant MIN_FFMT = power(10, -4)
public function format(sequence format_pattern, object arg_list = {})
sequence result
@@ -1456,6 +1454,7 @@
object envvar
integer ep
integer pflag
+ integer round
integer count
sequence fmt
atom argval
@@ -1572,12 +1571,17 @@
case '.' then
decs = 0
+ round = 0
while i < length(format_pattern) do
i += 1
tch = format_pattern[i]
pos = find(tch, "0123456789")
if pos = 0 then
- i -= 1
+ if tch = 'r' then
+ round = MAX_DIGS
+ else
+ i -= 1
+ end if
exit
end if
decs = decs * 10 + pos - 1
@@ -1783,14 +1787,31 @@
argval = -argval
end if
if decs < 0 then
- fmt = sprintf("%%.%dg", MAX_DIGS) -- default '%g' format precision
- elsif argval >= power(10, 15) or
- argval < 1e-4 then
- fmt = sprintf("%%.%de", decs)
+ fmt = sprintf("%%.%dg", MAX_DIGS)
+ elsif argval >= MAX_FFMT or
+ argval < MIN_FFMT then
+ fmt = sprintf("%%.%de", decs + MAX_DIGS - round)
else
- fmt = sprintf("%%.%df", decs)
+ fmt = sprintf("%%.%df", decs + MAX_DIGS - round)
end if
argtext = sprintf(fmt, arg_list[argn])
+ pos = find('e', argtext)
+ if pos = 0 then
+ if decs >= 0 then
+ argtext = argtext[ 1 .. $ - MAX_DIGS + round ]
+ end if
+ if argtext[$] = '.' then
+ argtext = argtext[ 1 .. $ - 1 ]
+ end if
+ else
+ sequence arg1 = argtext[ 1 .. pos - 1 - MAX_DIGS + round ]
+ if decs >= 0 then
+ if arg1[$] = '.' then
+ arg1 = arg1[ 1 .. $ - 1 ]
+ end if
+ end if
+ argtext = arg1 & argtext[ pos .. $ ]
+ end if
-- Remove any leading 0 after e+
while ep != 0 with entry do
argtext = remove(argtext, ep+2)

