mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Add engineering output mode
Similar to scientific mode, engineering mode also displays numbers in base 10 exponential notation, with the difference that exponents are always multiples of 3, to facilitate the interpretation in terms of SI prefixes. The mode is activated in config thru "engineering" or "eng. For base and base2, it uses the special value 1000.
This commit is contained in:
2
config.c
2
config.c
@@ -274,6 +274,8 @@ STATIC NAMETYPE modes[] = {
|
|||||||
{"scientific", MODE_EXP},
|
{"scientific", MODE_EXP},
|
||||||
{"sci", MODE_EXP},
|
{"sci", MODE_EXP},
|
||||||
{"exp", MODE_EXP},
|
{"exp", MODE_EXP},
|
||||||
|
{"engineering", MODE_ENG},
|
||||||
|
{"eng", MODE_ENG},
|
||||||
{"hexadecimal", MODE_HEX},
|
{"hexadecimal", MODE_HEX},
|
||||||
{"hex", MODE_HEX},
|
{"hex", MODE_HEX},
|
||||||
{"octal", MODE_OCTAL},
|
{"octal", MODE_OCTAL},
|
||||||
|
3
file.c
3
file.c
@@ -1048,6 +1048,9 @@ idprintf(FILEID id, char *fmt, int count, VALUE **vals)
|
|||||||
case 'e':
|
case 'e':
|
||||||
newmode = MODE_EXP;
|
newmode = MODE_EXP;
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
newmode = MODE_ENG;
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
newmode = MODE_REAL_AUTO;
|
newmode = MODE_REAL_AUTO;
|
||||||
break;
|
break;
|
||||||
|
12
func.c
12
func.c
@@ -7839,6 +7839,9 @@ f_base(int count, NUMBER **vals)
|
|||||||
case 16:
|
case 16:
|
||||||
oldbase = math_setmode(MODE_HEX);
|
oldbase = math_setmode(MODE_HEX);
|
||||||
break;
|
break;
|
||||||
|
case 1000:
|
||||||
|
oldbase = math_setmode(MODE_ENG);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
math_error("Unsupported base");
|
math_error("Unsupported base");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@@ -7893,6 +7896,9 @@ f_base2(int count, NUMBER **vals)
|
|||||||
case 16:
|
case 16:
|
||||||
oldbase = math_setmode2(MODE_HEX);
|
oldbase = math_setmode2(MODE_HEX);
|
||||||
break;
|
break;
|
||||||
|
case 1000:
|
||||||
|
oldbase = math_setmode(MODE_ENG);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
math_error("Unsupported base");
|
math_error("Unsupported base");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@@ -7933,6 +7939,9 @@ base_value(long mode, int defval)
|
|||||||
result = qalloc();
|
result = qalloc();
|
||||||
ztenpow(20, &result->num);
|
ztenpow(20, &result->num);
|
||||||
break;
|
break;
|
||||||
|
case MODE_ENG:
|
||||||
|
result = itoq(1000);
|
||||||
|
break;
|
||||||
case MODE_HEX:
|
case MODE_HEX:
|
||||||
result = itoq(16);
|
result = itoq(16);
|
||||||
break;
|
break;
|
||||||
@@ -7964,6 +7973,9 @@ base_value(long mode, int defval)
|
|||||||
result = qalloc();
|
result = qalloc();
|
||||||
ztenpow(20, &result->num);
|
ztenpow(20, &result->num);
|
||||||
break;
|
break;
|
||||||
|
case MODE_ENG:
|
||||||
|
result = itoq(1000);
|
||||||
|
break;
|
||||||
case MODE_HEX:
|
case MODE_HEX:
|
||||||
result = itoq(16);
|
result = itoq(16);
|
||||||
break;
|
break;
|
||||||
|
@@ -44,6 +44,9 @@ DESCRIPTION
|
|||||||
"sci"
|
"sci"
|
||||||
"exp"
|
"exp"
|
||||||
|
|
||||||
|
1000 "engineering" base 10 notation with exponent
|
||||||
|
"eng" multiple of 3
|
||||||
|
|
||||||
For convenience, any non-integer value is assumed to mean base 10
|
For convenience, any non-integer value is assumed to mean base 10
|
||||||
fractions and any integer >= 2^64 is assumed to mean base 10
|
fractions and any integer >= 2^64 is assumed to mean base 10
|
||||||
scientific notation.
|
scientific notation.
|
||||||
@@ -76,7 +79,7 @@ LINK LIBRARY
|
|||||||
int math_setmode(int newmode)
|
int math_setmode(int newmode)
|
||||||
|
|
||||||
NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT,
|
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
|
SEE ALSO
|
||||||
base2, config, str
|
base2, config, str
|
||||||
|
@@ -50,6 +50,9 @@ DESCRIPTION
|
|||||||
"sci"
|
"sci"
|
||||||
"exp"
|
"exp"
|
||||||
|
|
||||||
|
1000 "engineering" base 10 notation with exponent
|
||||||
|
"eng" multiple of 3
|
||||||
|
|
||||||
0 "off" disable double base output
|
0 "off" disable double base output
|
||||||
|
|
||||||
For convenience, any non-integer non-zero value is assumed to mean
|
For convenience, any non-integer non-zero value is assumed to mean
|
||||||
@@ -87,7 +90,7 @@ LINK LIBRARY
|
|||||||
int math_setmode2(int newmode)
|
int math_setmode2(int newmode)
|
||||||
|
|
||||||
NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT,
|
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
|
MODE2_OFF
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
|
@@ -165,8 +165,8 @@ DESCRIPTION
|
|||||||
config("display", int)
|
config("display", int)
|
||||||
|
|
||||||
The "display" parameter specifies the maximum number of digits after
|
The "display" parameter specifies the maximum number of digits after
|
||||||
the decimal point to be printed in real or exponential mode in
|
the decimal point to be printed in real, exponential or engineering
|
||||||
normal unformatted printing (print, strprint, fprint) or in
|
mode in normal unformatted printing (print, strprint, fprint) or in
|
||||||
formatted printing (printf, strprintf, fprintf) when precision is not
|
formatted printing (printf, strprintf, fprintf) when precision is not
|
||||||
specified. The initial value for oldstd is 20, for newstd 10.
|
specified. The initial value for oldstd is 20, for newstd 10.
|
||||||
The parameter may be changed to the value d by either
|
The parameter may be changed to the value d by either
|
||||||
@@ -234,6 +234,9 @@ DESCRIPTION
|
|||||||
"sci"
|
"sci"
|
||||||
"exp"
|
"exp"
|
||||||
|
|
||||||
|
"engineering" base 10 notation with exponent base(10e6)
|
||||||
|
"eng" multiple of 3
|
||||||
|
|
||||||
Where multiple strings are given, the first string listed is what
|
Where multiple strings are given, the first string listed is what
|
||||||
config("mode") will return.
|
config("mode") will return.
|
||||||
|
|
||||||
|
31
qio.c
31
qio.c
@@ -247,6 +247,37 @@ qprintnum(NUMBER *q, int outmode, LEN outdigits)
|
|||||||
PRINTF1("e%ld", exp);
|
PRINTF1("e%ld", exp);
|
||||||
break;
|
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:
|
case MODE_REAL_AUTO:
|
||||||
{
|
{
|
||||||
const int P = conf->outdigits ? conf->outdigits : 1;
|
const int P = conf->outdigits ? conf->outdigits : 1;
|
||||||
|
3
zmath.h
3
zmath.h
@@ -594,7 +594,8 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res);
|
|||||||
#define MODE_OCTAL 6
|
#define MODE_OCTAL 6
|
||||||
#define MODE_BINARY 7
|
#define MODE_BINARY 7
|
||||||
#define MODE_REAL_AUTO 8
|
#define MODE_REAL_AUTO 8
|
||||||
#define MODE_MAX 8
|
#define MODE_ENG 9
|
||||||
|
#define MODE_MAX 9
|
||||||
#define MODE2_OFF (MODE_MAX+1)
|
#define MODE2_OFF (MODE_MAX+1)
|
||||||
|
|
||||||
/* XXX - perhaps we need the MODE_REAL_AUTO vs MODE_REAL as a config mode? */
|
/* XXX - perhaps we need the MODE_REAL_AUTO vs MODE_REAL as a config mode? */
|
||||||
|
Reference in New Issue
Block a user