[PATCH 5/5] Allow printing fltXY in scientific notation
[Thread Prev] | [Thread Next]
[Date Prev] | [Date Next]
- Subject: [PATCH 5/5] Allow printing fltXY in scientific notation
- From: "S. Gilles" <sgilles@xxxxxxxxxxxx>
- Reply-to: myrddin-dev@xxxxxxxxxxxxxx
- Date: Mon, 9 Sep 2019 08:38:29 -0400
- To: "myrddin-dev" <myrddin-dev@xxxxxxxxxxxxxx>
- Cc: "S. Gilles" <sgilles@xxxxxxxxxxxx>
--- Also includes a oneline fix for option parsing for things like `std.put("{x,p=Y}\n", 123)'. lib/std/fltfmt.myr | 28 +++++++++++++------ lib/std/fmt.myr | 3 +++ lib/std/test/fltfmt.myr | 60 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/lib/std/fltfmt.myr b/lib/std/fltfmt.myr index 25b1583b..570da488 100644 --- a/lib/std/fltfmt.myr +++ b/lib/std/fltfmt.myr @@ -3,6 +3,7 @@ use "bigint" use "die" use "extremum" use "fltbits" +use "intfmt" use "option" use "slpush" use "strbuf" @@ -16,10 +17,11 @@ pkg std = pkglocal const MRelative = 2 pkglocal type fltparams = struct - mode : int - cutoff : size - padto : size - padfill : char + mode : int + cutoff : size + scientific : bool + padto : size + padfill : char ;; pkglocal const flt64bfmt : (sb : strbuf#, opts : fltparams, val : flt64 -> void) @@ -45,7 +47,7 @@ const flt64bfmt = {sb, opts, val var valsb = mksb() exp = max(exp, 1 - Dblbias) - dragon4(valsb, false, mant, exp - 52, Dblbias, opts.mode, opts.cutoff) + dragon4(valsb, false, mant, exp - 52, Dblbias, opts.mode, opts.cutoff, opts.scientific) -> blobfmt(sb, sbfin(valsb), opts, isneg) } @@ -66,7 +68,7 @@ const flt32bfmt = {sb, opts, val var valsb = mksb() exp = (max((exp : int64), 1 - Fltbias) : int32) - dragon4(valsb, false, (mant : uint64), (exp - 23 : int64), Fltbias, opts.mode, opts.cutoff) + dragon4(valsb, false, (mant : uint64), (exp - 23 : int64), Fltbias, opts.mode, opts.cutoff, opts.scientific) -> blobfmt(sb, sbfin(valsb), opts, isneg) } @@ -130,13 +132,14 @@ f: mantissa floating value: x = f^(e - p) */ -const dragon4 = {sb, isneg, f, e, p, mode, cutoff +const dragon4 = {sb, isneg, f, e, p, mode, cutoff, scientific var r, s, t, u, v, y var udig var mm, mp /* margins above and below */ var roundup var low, high var k + var tenpower : int64 = 0 var a, i if isneg @@ -252,6 +255,11 @@ const dragon4 = {sb, isneg, f, e, p, mode, cutoff ;; ;; + if scientific + tenpower = (k - 1 : int64) + k = 1 + ;; + if k <= 0 sbputs(sb, "0.") for var i = 0; i < -k; i++ @@ -320,12 +328,16 @@ const dragon4 = {sb, isneg, f, e, p, mode, cutoff format(sb, 0, k--) ;; + if scientific + sbputs(sb, "e") + intfmt(sb, [ .base = 10 ], true, (tenpower : uint64), 64) + ;; + bigfree(u) bigfree(r) bigfree(s) bigfree(mm) bigfree(mp) - } const lowdig = {u diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr index b981a74f..c4c3797e 100644 --- a/lib/std/fmt.myr +++ b/lib/std/fmt.myr @@ -210,6 +210,7 @@ const sbfmtv = {sb, fmt, ap -> size if startp != nbuf param[nparam++] = (buf[startp:nbuf], "") ;; + startp = nbuf | (`ParamOpt, '}'): state = `Copy if startp != nbuf @@ -455,12 +456,14 @@ const fltparams = {params fp = [ .mode = MNormal, .cutoff = 0, + .scientific = false, .padfill = ' ', .padto = 0, ] for p : params match p + | ("e", ""): fp.scientific = true | ("w", wid): fp.padto = getint(wid, "fmt: width must be integer") | ("p", pad): fp.padfill = decode(pad) | ("s", sig): diff --git a/lib/std/test/fltfmt.myr b/lib/std/test/fltfmt.myr index 7e844dd7..0ef790b2 100644 --- a/lib/std/test/fltfmt.myr +++ b/lib/std/test/fltfmt.myr @@ -12,6 +12,8 @@ const main = { [.name = "putlowprec", .fn = putlowprec], [.name = "padding", .fn = padding], [.name = "sigfigs", .fn = sigfigs], + [.name = "scientific01", .fn = scientific01], + [.name = "scientific02", .fn = scientific02], ][:]) } @@ -167,3 +169,61 @@ const sigfigs = {c act = std.fmt("{s=-23}", f32) testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) } + +const scientific01 = {c + var exp, act + var f32 : flt32 + var f64 : flt64 + + f32 = 9.125 + exp = "9.125e0" + act = std.fmt("{e}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f32 = -9.125 + exp = "-9.125e0" + act = std.fmt("{e}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f32 = 101.25 + exp = "1.0125e2" + act = std.fmt("{e}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f64 = 0.000345 + exp = "3.45e-4" + act = std.fmt("{e}", f64) + testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act) + + f64 = 0.0 + exp = "0.0" + act = std.fmt("{e}", f64) + testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act) +} + +const scientific02 = {c + var exp, act + var f32 : flt32 + var f64 : flt64 + + f32 = 9.125 + exp = "9.1e0" + act = std.fmt("{s=2,e}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f32 = 9.125 + exp = "9.1e0" + act = std.fmt("{e,s=2}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f32 = 9.125 + exp = "9.0e0" + act = std.fmt("{e,s=1}", f32) + testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act) + + f64 = -0.000345 + exp = "-3.4e-4" + act = std.fmt("{e,s=2}", f64) + testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act) + +} -- 2.23.0
[PATCH 0/5] Allow printing floating point in scientific notation | "S. Gilles" <sgilles@xxxxxxxxxxxx> |
- Prev by Date: [PATCH 4/5] Split out intfmt to a separate file.
- Previous by thread: [PATCH 4/5] Split out intfmt to a separate file.
- Index(es):