shithub: mc

Download patch

ref: b5ddbc86346fddc60360a817ee62bc8ca938973e
parent: d58df01f3ea2de8d41e10d5387445027e59a6c4e
author: S. Gilles <sgilles@math.umd.edu>
date: Mon Sep 9 03:10:55 EDT 2019

Specify sigfigs (cutoff + Relative mode) for fltXY formatting

--- a/lib/std/fltfmt.myr
+++ b/lib/std/fltfmt.myr
@@ -17,7 +17,7 @@
 
 	pkglocal type fltparams = struct
 		mode	: int
-		prec	: int
+		cutoff	: size
 		padto	: size
 		padfill	: char
 	;;
@@ -45,7 +45,7 @@
 	var valsb = mksb()
 
 	exp = max(exp, 1 - Dblbias)
-	dragon4(valsb, false, mant, exp - 52, Dblbias, opts.mode, opts.prec)
+	dragon4(valsb, false, mant, exp - 52, Dblbias, opts.mode, opts.cutoff)
 
 	-> blobfmt(sb, sbfin(valsb), opts, isneg)
 }
@@ -66,7 +66,7 @@
 	var valsb = mksb()
 
 	exp = (max((exp : int64), 1 - Fltbias) : int32)
-	dragon4(valsb, false, (mant : uint64), (exp - 23 : int64), Fltbias, opts.mode, opts.prec)
+	dragon4(valsb, false, (mant : uint64), (exp - 23 : int64), Fltbias, opts.mode, opts.cutoff)
 
 	-> blobfmt(sb, sbfin(valsb), opts, isneg)
 }
@@ -209,16 +209,19 @@
 		else
 			if mode == MRelative
 				cutoff += k - 1
+				a = cutoff - k + 1
+			else
+				a = cutoff
 			;;
+
 			/* common between relative and absolute */
-			a = cutoff - k - 1
 			y = bigdup(s)
 			if a < 0
-				for i = 0; i < a; i++
+				for i = 0; i < -a; i++
 					bigmuli(y, 10)
 				;;
 			else
-				for i = 0; i < -a; i++
+				for i = 0; i < a; i++
 					bigaddi(y, 9)
 					bigdivi(y, 10)
 				;;
@@ -227,15 +230,16 @@
 			| `Before:	/* nothing */
 			| _:
 				bigfree(mm)
-				mm = y
+				mm = bigdup(y)
 			;;
 			match bigcmp(y, mp)
 			| `Before:	/* nothing */
 			| _:
 				bigfree(mp)
-				mp = y
+				mp = bigdup(y)
 				roundup = true
 			;;
+			bigfree(y)
 		;;
 		u = bigdup(s)
 		bigshli(u, 1)
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -453,7 +453,7 @@
 
 	fp = [
 		.mode = MNormal,
-		.prec = 0,
+		.cutoff = 0,
 		.padfill = ' ',
 		.padto = 0,
 	]
@@ -462,6 +462,9 @@
 		match p
 		| ("w", wid):	fp.padto = getint(wid, "fmt: width must be integer")
 		| ("p", pad):	fp.padfill = decode(pad)
+		| ("s", sig):
+			fp.mode = MRelative
+			fp.cutoff = getint(sig, "fmt: significant figures must be integer")
 		| (opt, arg):
 			std.write(2, "fmt: ")
 			std.write(2, opt)
--- a/lib/std/test/fltfmt.myr
+++ b/lib/std/test/fltfmt.myr
@@ -11,6 +11,7 @@
 		[.name = "putinteger", .fn = putinteger],
 		[.name = "putlowprec", .fn = putlowprec],
 		[.name = "padding", .fn = padding],
+		[.name = "sigfigs", .fn = sigfigs],
 	][:])
 }
 
@@ -88,7 +89,7 @@
 	f64 = 1.0
 	exp = "XXXX1.0"
 	act = std.fmt("{w=7,p=X}", f64)
-	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f64, exp, act)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
 
 	f32 = -2.5
 	exp = "YYYYYY-2.5"
@@ -98,7 +99,7 @@
 	f64 = -100000.5
 	exp = "-100000.5"
 	act = std.fmt("{w=9,p=Y}", f64)
-	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f64, exp, act)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
 
 	f32 = -13.25
 	exp = "-013.25"
@@ -113,5 +114,56 @@
 	f64 = std.flt64nan()
 	exp = "               NaN"
 	act = std.fmt("{w=18,p= }", f64)
-	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f64, exp, act)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+}
+
+const sigfigs = {c
+	var exp, act
+	var f32 : flt32
+	var f64 : flt64
+
+	f32 = 9.1234
+	exp = "9.12"
+	act = std.fmt("{s=3}", f32)
+	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act)
+
+	f64 = 19.1234
+	exp = "19.123"
+	act = std.fmt("{s=5}", f64)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+
+	f64 = 104.9
+	exp = "100.0"
+	act = std.fmt("{s=2}", f64)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+
+	f64 = 105.1
+	exp = "110.0"
+	act = std.fmt("{s=2}", f64)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+
+	f64 = 12345.6789
+	exp = "12345.6789"
+	act = std.fmt("{s=200}", f64)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+
+	f64 = 12345.6789
+	exp = "12345.679"
+	act = std.fmt("{s=8}", f64)
+	testr.check(c, std.eq(exp, act), "{} should format [flt64] to \"{}\", was \"{}\"", f64, exp, act)
+
+	f32 = -13.49
+	exp = "-13.5"
+	act = std.fmt("{s=3}", f32)
+	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act)
+
+	f32 = -13.53
+	exp = "-13.5"
+	act = std.fmt("{s=3}", f32)
+	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act)
+
+	f32 = -13.53
+	exp = "-10.0"
+	act = std.fmt("{s=-23}", f32)
+	testr.check(c, std.eq(exp, act), "{} should format [flt32] to \"{}\", was \"{}\"", f32, exp, act)
 }