diff --git a/config.c b/config.c index 96416a0..6801e57 100644 --- a/config.c +++ b/config.c @@ -274,6 +274,8 @@ STATIC NAMETYPE modes[] = { {"scientific", MODE_EXP}, {"sci", MODE_EXP}, {"exp", MODE_EXP}, + {"engineering", MODE_ENG}, + {"eng", MODE_ENG}, {"hexadecimal", MODE_HEX}, {"hex", MODE_HEX}, {"octal", MODE_OCTAL}, diff --git a/file.c b/file.c index ecd15f3..68dc6a4 100644 --- a/file.c +++ b/file.c @@ -1048,6 +1048,9 @@ idprintf(FILEID id, char *fmt, int count, VALUE **vals) case 'e': newmode = MODE_EXP; break; + case 'n': + newmode = MODE_ENG; + break; case 'g': newmode = MODE_REAL_AUTO; break; diff --git a/func.c b/func.c index c03cf7b..9e92794 100644 --- a/func.c +++ b/func.c @@ -7839,6 +7839,9 @@ f_base(int count, NUMBER **vals) case 16: oldbase = math_setmode(MODE_HEX); break; + case 1000: + oldbase = math_setmode(MODE_ENG); + break; default: math_error("Unsupported base"); /*NOTREACHED*/ @@ -7893,6 +7896,9 @@ f_base2(int count, NUMBER **vals) case 16: oldbase = math_setmode2(MODE_HEX); break; + case 1000: + oldbase = math_setmode(MODE_ENG); + break; default: math_error("Unsupported base"); /*NOTREACHED*/ @@ -7933,6 +7939,9 @@ base_value(long mode, int defval) result = qalloc(); ztenpow(20, &result->num); break; + case MODE_ENG: + result = itoq(1000); + break; case MODE_HEX: result = itoq(16); break; @@ -7964,6 +7973,9 @@ base_value(long mode, int defval) result = qalloc(); ztenpow(20, &result->num); break; + case MODE_ENG: + result = itoq(1000); + break; case MODE_HEX: result = itoq(16); break; diff --git a/help/base b/help/base index 47208c5..15cf5ac 100644 --- a/help/base +++ b/help/base @@ -44,6 +44,9 @@ DESCRIPTION "sci" "exp" + 1000 "engineering" base 10 notation with exponent + "eng" multiple of 3 + For convenience, any non-integer value is assumed to mean base 10 fractions and any integer >= 2^64 is assumed to mean base 10 scientific notation. @@ -76,7 +79,7 @@ LINK LIBRARY int math_setmode(int newmode) NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT, - MODE_REAL, MODE_EXP, MODE_HEX, MODE_OCTAL, MODE_BINARY + MODE_REAL, MODE_EXP, MODE_ENG, MODE_HEX, MODE_OCTAL, MODE_BINARY SEE ALSO base2, config, str diff --git a/help/base2 b/help/base2 index bac9ca7..e64aa53 100644 --- a/help/base2 +++ b/help/base2 @@ -50,6 +50,9 @@ DESCRIPTION "sci" "exp" + 1000 "engineering" base 10 notation with exponent + "eng" multiple of 3 + 0 "off" disable double base output For convenience, any non-integer non-zero value is assumed to mean @@ -87,7 +90,7 @@ LINK LIBRARY int math_setmode2(int newmode) NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT, - MODE_REAL, MODE_EXP, MODE_HEX, MODE_OCTAL, MODE_BINARY, + MODE_REAL, MODE_EXP, MODE_ENG, MODE_HEX, MODE_OCTAL, MODE_BINARY, MODE2_OFF SEE ALSO diff --git a/help/config b/help/config index 380744d..4f10398 100644 --- a/help/config +++ b/help/config @@ -165,8 +165,8 @@ DESCRIPTION config("display", int) The "display" parameter specifies the maximum number of digits after - the decimal point to be printed in real or exponential mode in - normal unformatted printing (print, strprint, fprint) or in + the decimal point to be printed in real, exponential or engineering + mode in normal unformatted printing (print, strprint, fprint) or in formatted printing (printf, strprintf, fprintf) when precision is not specified. The initial value for oldstd is 20, for newstd 10. The parameter may be changed to the value d by either @@ -234,6 +234,9 @@ DESCRIPTION "sci" "exp" + "engineering" base 10 notation with exponent base(10e6) + "eng" multiple of 3 + Where multiple strings are given, the first string listed is what config("mode") will return. diff --git a/qio.c b/qio.c index d3170c2..4b0a15d 100644 --- a/qio.c +++ b/qio.c @@ -247,6 +247,37 @@ qprintnum(NUMBER *q, int outmode, LEN outdigits) PRINTF1("e%ld", exp); break; + case MODE_ENG: + if (qiszero(q)) { + PUTCHAR('0'); + return; + } + tmpval = *q; + tmpval.num.sign = 0; + exp = qilog10(&tmpval); + if (exp == 0) { /* in range to output as real */ + qprintnum(q, MODE_REAL, outdigits); + return; + } + tmpval.num = _one_; + tmpval.den = _one_; + if (exp > 0) { + exp -= exp % 3; + ztenpow(exp, &tmpval.den); + } else { + long remainder = exp % 3; + if (remainder) + exp -= remainder + 3; + ztenpow(-exp, &tmpval.num); + } + q = qmul(q, &tmpval); + zfree(tmpval.num); + zfree(tmpval.den); + qprintnum(q, MODE_REAL, outdigits); + qfree(q); + PRINTF1("e%ld", exp); + break; + case MODE_REAL_AUTO: { const int P = conf->outdigits ? conf->outdigits : 1; diff --git a/zmath.h b/zmath.h index 83aa942..bc9613f 100644 --- a/zmath.h +++ b/zmath.h @@ -594,7 +594,8 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res); #define MODE_OCTAL 6 #define MODE_BINARY 7 #define MODE_REAL_AUTO 8 -#define MODE_MAX 8 +#define MODE_ENG 9 +#define MODE_MAX 9 #define MODE2_OFF (MODE_MAX+1) /* XXX - perhaps we need the MODE_REAL_AUTO vs MODE_REAL as a config mode? */