Re: text.e bugs?
- Posted by cargoan Jan 24, 2015
- 1814 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)