mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Improvements to %g pull request
This code %g is preliminary. Fixed some code style issues to match the current code style. Added regression tests and help file updates to printf and strprintf. Fixed use of magic number -4: using -P instead. Noted two problem areas with XXX comments in qio.c: 1) need a qprintfg function 2) re-write to not modify conf->outdigits
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -17,6 +17,9 @@ The following are the changes from calc version 2.12.6.9 to date:
|
|||||||
Added regression tests 3729 thru 3732 to test E_TAN3, E_COT3,
|
Added regression tests 3729 thru 3732 to test E_TAN3, E_COT3,
|
||||||
E_SEC3 and E_CSC3 respectively.
|
E_SEC3 and E_CSC3 respectively.
|
||||||
|
|
||||||
|
Added experimential %g printf (and strprintf) format implementation
|
||||||
|
based on pull request from github user 10110111.
|
||||||
|
|
||||||
|
|
||||||
The following are the changes from calc version 2.12.6.6 to 2.12.6.8:
|
The following are the changes from calc version 2.12.6.6 to 2.12.6.8:
|
||||||
|
|
||||||
|
@@ -4106,38 +4106,46 @@ define test_strprintf()
|
|||||||
'4821: strprintf("%b", 27/29) == "0b11011/0b11101"');
|
'4821: strprintf("%b", 27/29) == "0b11011/0b11101"');
|
||||||
vrfy(strprintf("%e", 12345) == "~1.23e4",
|
vrfy(strprintf("%e", 12345) == "~1.23e4",
|
||||||
'4822: strprintf("%e", 12345) == "~1.23e4"');
|
'4822: strprintf("%e", 12345) == "~1.23e4"');
|
||||||
|
vrfy(strprintf("%g", .385) == "~.38",
|
||||||
|
'4823: strprintf("%g", .385) == "~.38"');
|
||||||
|
vrfy(strprintf("%g", 385) == "~3.8e2",
|
||||||
|
'4824: strprintf("%g", 385) == "~3.8e2"');
|
||||||
|
|
||||||
/* mode tests with tilde == 0 */
|
/* mode tests with tilde == 0 */
|
||||||
c = config("tilde", 0);
|
c = config("tilde", 0);
|
||||||
print '4823: c = config("tilde", 0)';
|
print '4825: c = config("tilde", 0)';
|
||||||
vrfy(strprintf("%e", 12345) == "1.23e4",
|
vrfy(strprintf("%e", 12345) == "1.23e4",
|
||||||
'4824: strprintf("%e", 12345) == "1.23e4"');
|
'4826: strprintf("%e", 12345) == "1.23e4"');
|
||||||
vrfy(strprintf("%.3e", 12345) == "1.234e4",
|
vrfy(strprintf("%.3e", 12345) == "1.234e4",
|
||||||
'4825: strprintf("%.3e", 12345) == "1.234e4"');
|
'4827: strprintf("%.3e", 12345) == "1.234e4"');
|
||||||
vrfy(strprintf("%e", .00012345) == "1.23e-4",
|
vrfy(strprintf("%e", .00012345) == "1.23e-4",
|
||||||
'4826: strprintf("%e", .00012345) == "1.23e-4"');
|
'4828: strprintf("%e", .00012345) == "1.23e-4"');
|
||||||
vrfy(strprintf("%d %d", 27) == "27 ",
|
vrfy(strprintf("%d %d", 27) == "27 ",
|
||||||
'4827: strprintf("%d %d", 27) == "27 "');
|
'4829: strprintf("%d %d", 27) == "27 "');
|
||||||
vrfy(strprintf("%d", 27, 29) == "27",
|
vrfy(strprintf("%d", 27, 29) == "27",
|
||||||
'4828: strprintf("%d", 27, 29) == "27"');
|
'4830: strprintf("%d", 27, 29) == "27"');
|
||||||
vrfy(strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93",
|
vrfy(strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93",
|
||||||
'4829: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"');
|
'4831: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"');
|
||||||
vrfy(strprintf("%s", "abc") == "abc",
|
vrfy(strprintf("%s", "abc") == "abc",
|
||||||
'4830: strprintf("%s", "abc") == "abc"');
|
'4832: strprintf("%s", "abc") == "abc"');
|
||||||
vrfy(strprintf("%f", "abc") == "abc",
|
vrfy(strprintf("%f", "abc") == "abc",
|
||||||
'4831: strprintf("%f", "abc") == "abc"');
|
'4833: strprintf("%f", "abc") == "abc"');
|
||||||
vrfy(strprintf("%e", "abc") == "abc",
|
vrfy(strprintf("%e", "abc") == "abc",
|
||||||
'4832: strprintf("%e", "abc") == "abc"');
|
'4834: strprintf("%e", "abc") == "abc"');
|
||||||
vrfy(strprintf("%5s", "abc") == " abc",
|
vrfy(strprintf("%5s", "abc") == " abc",
|
||||||
'4833: strprintf("%5s", "abc") == " abc"');
|
'4835: strprintf("%5s", "abc") == " abc"');
|
||||||
vrfy(strprintf("%-5s", "abc") == "abc ",
|
vrfy(strprintf("%-5s", "abc") == "abc ",
|
||||||
'4834: strprintf("%-5s", "abc") == "abc "');
|
'4836: strprintf("%-5s", "abc") == "abc "');
|
||||||
|
vrfy(strprintf("%g", .385) == ".38",
|
||||||
|
'4837: strprintf("%g", .385) == ".38"');
|
||||||
|
vrfy(strprintf("%g", 385) == "3.8e2",
|
||||||
|
'4838: strprintf("%g", 385) == "3.8e2"');
|
||||||
|
|
||||||
/* restore config */
|
/* restore config */
|
||||||
c = config("all", callcfg);
|
c = config("all", callcfg);
|
||||||
print '4835: c = config("all", callcfg)';
|
print '4839: c = config("all", callcfg)';
|
||||||
|
|
||||||
print '4836: Ending test_strprintf';
|
print '4840: Ending test_strprintf';
|
||||||
}
|
}
|
||||||
print '088: parsed test_fileop()';
|
print '088: parsed test_fileop()';
|
||||||
|
|
||||||
|
44
help/printf
44
help/printf
@@ -28,7 +28,7 @@ DESCRIPTION
|
|||||||
zero or more decimal digits
|
zero or more decimal digits
|
||||||
an optional '. followed by zero or more decimal deigits
|
an optional '. followed by zero or more decimal deigits
|
||||||
an optional 'l'
|
an optional 'l'
|
||||||
one of the letters: d, s, c, f, e, r, o, x, b,
|
one of the letters: d, s, c, f, e, g, r, o, x, b,
|
||||||
|
|
||||||
If any other character is read, the '%' and any characters
|
If any other character is read, the '%' and any characters
|
||||||
between '%' and the character are ignored and no specifier is
|
between '%' and the character are ignored and no specifier is
|
||||||
@@ -51,26 +51,27 @@ DESCRIPTION
|
|||||||
d, s, c current config("mode")
|
d, s, c current config("mode")
|
||||||
f real (decimal, floating point)
|
f real (decimal, floating point)
|
||||||
e exponential
|
e exponential
|
||||||
|
g real or exponential depending on config("display")
|
||||||
r fractional
|
r fractional
|
||||||
o octal
|
o octal
|
||||||
x hexadecimal
|
x hexadecimal
|
||||||
b binary
|
b binary
|
||||||
|
|
||||||
If the number of arguments after fmt is less than the
|
If the number of arguments after fmt is less than the number
|
||||||
number of format specifiers in fmt, the "missing" arguments
|
of format specifiers in fmt, the "missing" arguments may be
|
||||||
may be taken to be null values - these contribute nothing to the
|
taken to be null values - these contribute nothing to the output;
|
||||||
output; if a positive width w has been specified, the effect is
|
if a positive width w has been specified, the effect is to
|
||||||
to produce w spaces, e.g. printf("abc%6dxyz") prints "abc xyz".
|
produce w spaces, e.g., printf("abc%6dxyz") prints "abc xyz".
|
||||||
|
|
||||||
If i <= the number of specifiers in fmt, the value of argument x_i
|
If i <= the number of specifiers in fmt, the value of argument
|
||||||
is printed in the format specified by the i-th specifier.
|
x_i is printed in the format specified by the i-th specifier.
|
||||||
If a positive width w has been specified and normal printing of x_i
|
If a positive width w has been specified and normal printing
|
||||||
does not include a '\n' character, what is printed will if necessary
|
of x_i does not include a '\n' character, what is printed will
|
||||||
be padded with spaces so that the length of the printed output
|
if necessary be padded with spaces so that the length of the
|
||||||
is at least the w. Note that control
|
printed output is at least the w. Note that control characters
|
||||||
characters like '\t', '\b' each count as one character. If
|
like '\t', '\b' each count as one character. If the 'right-pad'
|
||||||
the 'right-pad' flag has been set, the padding is on the right;
|
flag has been set, the padding is on the right; otherwise it
|
||||||
otherwise it is on the left.
|
is on the left.
|
||||||
|
|
||||||
If i > the number of specifiers in fmt, the value of argument x_i
|
If i > the number of specifiers in fmt, the value of argument x_i
|
||||||
does not contribute to the printing. However, as all arguments
|
does not contribute to the printing. However, as all arguments
|
||||||
@@ -84,9 +85,9 @@ DESCRIPTION
|
|||||||
mode.
|
mode.
|
||||||
|
|
||||||
In the case of floating-point (f) format the precision determines
|
In the case of floating-point (f) format the precision determines
|
||||||
the maximum number of decimal places to be
|
the maximum number of decimal places to be displayed. Other
|
||||||
displayed. Other aspects of this printing may be affected by the
|
aspects of this printing may be affected by the configuration
|
||||||
configuration parameters "outround", "tilde", "fullzero", "leadzero".
|
parameters "outround", "tilde", "fullzero", "leadzero".
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
; c = config("epsilon", 1e-6); c = config("display", 6);
|
; c = config("epsilon", 1e-6); c = config("display", 6);
|
||||||
@@ -116,6 +117,11 @@ EXAMPLE
|
|||||||
[2] = "undefined"
|
[2] = "undefined"
|
||||||
[3] = NULL
|
[3] = NULL
|
||||||
|
|
||||||
|
; c = config("display", 50);
|
||||||
|
; printf("%g %g\n%g %g\n", 1e5, 1e49, 1e50, 1e500);
|
||||||
|
100000 100000000000000000000000000000000000000000000000000
|
||||||
|
1e50 1e500
|
||||||
|
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
The number of arguments of printf() is not to exceed 1024.
|
The number of arguments of printf() is not to exceed 1024.
|
||||||
@@ -126,7 +132,7 @@ LINK LIBRARY
|
|||||||
SEE ALSO
|
SEE ALSO
|
||||||
fprintf, strprintf, print
|
fprintf, strprintf, print
|
||||||
|
|
||||||
## Copyright (C) 1999-2006 Landon Curt Noll
|
## Copyright (C) 1999-2006,2018 Landon Curt Noll
|
||||||
##
|
##
|
||||||
## Calc is open software; you can redistribute it and/or modify it under
|
## Calc is open software; you can redistribute it and/or modify it under
|
||||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||||
|
@@ -27,6 +27,13 @@ EXAMPLE
|
|||||||
"1.732051, 1.732051,1.732051 , ~1.7320,~1.7320,~1.
|
"1.732051, 1.732051,1.732051 , ~1.7320,~1.7320,~1.
|
||||||
"
|
"
|
||||||
|
|
||||||
|
; c = config("display", 50);
|
||||||
|
; fmt2 = "%g %g\n%g %g\n"
|
||||||
|
; strprintf(fmt2, 1e5, 1e49, 1e50, 1e500);
|
||||||
|
"100000 100000000000000000000000000000000000000000000000000
|
||||||
|
1e50 1e500
|
||||||
|
"
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
The number of arguments of strprintf() is not to exceed 1024.
|
The number of arguments of strprintf() is not to exceed 1024.
|
||||||
|
|
||||||
@@ -39,7 +46,7 @@ SEE ALSO
|
|||||||
|
|
||||||
printf, fprintf, print
|
printf, fprintf, print
|
||||||
|
|
||||||
## Copyright (C) 1999-2006 Landon Curt Noll
|
## Copyright (C) 1999-2006,2018 Landon Curt Noll
|
||||||
##
|
##
|
||||||
## Calc is open software; you can redistribute it and/or modify it under
|
## Calc is open software; you can redistribute it and/or modify it under
|
||||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||||
|
24
qio.c
24
qio.c
@@ -97,6 +97,15 @@ qprintf(char *fmt, ...)
|
|||||||
q = va_arg(ap, NUMBER *);
|
q = va_arg(ap, NUMBER *);
|
||||||
qprintfe(q, width, precision);
|
qprintfe(q, width, precision);
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
q = va_arg(ap, NUMBER *);
|
||||||
|
/* XXX - we need a qprintfg function */
|
||||||
|
#if 0 /* XXX - we need a qprintfg() function */
|
||||||
|
qprintfg(q, width, precision);
|
||||||
|
#else /* XXX - use qprintfe until we have a qprintfg() function */
|
||||||
|
qprintfe(q, width, precision);
|
||||||
|
#endif /* XXX - we need a qprintfg() function */
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'R':
|
case 'R':
|
||||||
q = va_arg(ap, NUMBER *);
|
q = va_arg(ap, NUMBER *);
|
||||||
@@ -235,18 +244,23 @@ qprintnum(NUMBER *q, int outmode)
|
|||||||
|
|
||||||
case MODE_REAL_AUTO:
|
case MODE_REAL_AUTO:
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* XXX - re-write to not modify conf->outdigits
|
||||||
|
*
|
||||||
|
* Modifying the configuration value could be dangerious
|
||||||
|
* when a calculation is aborted within an opcode.
|
||||||
|
* Better to use qprintfg() use inline code that
|
||||||
|
* does not depend on changing conf->outdigits.
|
||||||
|
*/
|
||||||
const int P = conf->outdigits ? conf->outdigits : 1;
|
const int P = conf->outdigits ? conf->outdigits : 1;
|
||||||
tmpval = *q;
|
tmpval = *q;
|
||||||
tmpval.num.sign = 0;
|
tmpval.num.sign = 0;
|
||||||
exp = qilog10(&tmpval);
|
exp = qilog10(&tmpval);
|
||||||
const long olddigits = conf->outdigits;
|
const long olddigits = conf->outdigits;
|
||||||
if(P > exp && exp >= -4)
|
if (P > exp && exp >= -P) {
|
||||||
{
|
|
||||||
conf->outdigits = P - 1 - exp;
|
conf->outdigits = P - 1 - exp;
|
||||||
qprintnum(q, MODE_REAL);
|
qprintnum(q, MODE_REAL);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
conf->outdigits = P - 1;
|
conf->outdigits = P - 1;
|
||||||
qprintnum(q, MODE_EXP);
|
qprintnum(q, MODE_EXP);
|
||||||
}
|
}
|
||||||
|
5
zmath.h
5
zmath.h
@@ -583,7 +583,12 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res);
|
|||||||
#define MODE_MAX 8
|
#define MODE_MAX 8
|
||||||
#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? */
|
||||||
|
#if 0 /* XXX - can we safely set MODE_INITIAL to MODE_REAL_AUTO ?? */
|
||||||
#define MODE_INITIAL MODE_REAL_AUTO
|
#define MODE_INITIAL MODE_REAL_AUTO
|
||||||
|
#else
|
||||||
|
#define MODE_INITIAL MODE_REAL
|
||||||
|
#endif
|
||||||
#define MODE2_INITIAL MODE2_OFF
|
#define MODE2_INITIAL MODE2_OFF
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user