On Mon, Aug 19, 2013 at 8:10 PM, David Korn <[email protected]> wrote:
> cc: [email protected]
> Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON ))
> constants?
> --------
>> Erm... doesn't this just require a small modification of the
>> arithmetic engine (I don't know how to do the same for a plain
>> ${i.MAX}), e.g. do a type-based (technically we "only" have six types
>> - three integer and three float) lookup of the matching constant value
>> if an integer name is followed by a '.' ?
>
> First of all there are 9 types, 3 float, 3 integer, and 3 unsigned.
>
> Secondly, it is much simpler of i.MAX only appears in arithmetic
> expressions and cannot be used as ${i.MAX} because ${i.MAX} is
> more complex because it needs to work with ${i.MAX op string}
> and ${op i.MAX} as well.
>
> I am not even sure how to implement ${!i.M*} given the current
> architecture.
>
> Maybe I should restrict b.true to arithmetic expressions only.
> Programs that want ${i.MAX} can do $((i.MAX)).
>
> Anyway, I have enough bug reports to keep me busy for now.
Attached (as "astksh20130814_math_constants001.diff.txt") is a
prototype patch which allows constants to be defined like this:
-- snip --
$ ksh -o nounset -c 'compound .sh.mathconst=( float LDBL_M_PI=3.14 ) ;
float x=5.5 ; print $((x.M_PI)) ${x.M_PI}'
3.14 3.14
-- snip --
AFAIK we need the following constants (mostly derived from X/OPEN and
my own math code):
1. min/max/etc. limits:
-- snip --
# integer for $((i.MIN)) and $((i.MAX))
SHRT_MIN
SHRT_MAX
USHRT_MAX
INT_MIN
INT_MAX
UINT_MAX
LONG_MAX
LONG_MAX
LONG_MIN
ULONG_MAX
ULONG_MAX
# float for $((i.MANT_DIG , i.MIN_EXP , i.MIN_10_EXP, i.MAX_EXP ,
i.MAX_10_EXP , i.MIN , i.MAX, i.EPSILON , i.DECIMAL_DIG)
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
FLT_MIN_EXP
DBL_MIN_EXP
LDBL_MIN_EXP
FLT_MIN_10_EXP
DBL_MIN_10_EXP
LDBL_MIN_10_EXP
FLT_MAX_EXP
DBL_MAX_EXP
LDBL_MAX_EXP
FLT_MAX_10_EXP
DBL_MAX_10_EXP
LDBL_MAX_10_EXP
FLT_MAX
DBL_MAX
LDBL_MAX
FLT_EPSILON
DBL_EPSILON
LDBL_EPSILON
FLT_MIN
DBL_MIN
LDBL_MIN
FLT_DECIMAL_DIG
DBL_DECIMAL_DIG
LDBL_DECIMAL_DIG
-- snip --
2. constants (need to be per-type to get round-offs correct):
-- snip --
M_E 2.718281828459045235360287471352662498L /* e */
M_LOG2E 1.442695040888963407359924681001892137L /* log_2 e */
M_LOG10E 0.434294481903251827651128918916605082L /* log_10 e */
M_LN2 0.693147180559945309417232121458176568L /* log_e 2 */
M_LN10 2.302585092994045684017991454684364208L /* log_e 10 */
M_PI 3.141592653589793238462643383279502884L /* pi */
M_PI_2 1.570796326794896619231321691639751442L /* pi/2 */
M_PI_4 0.785398163397448309615660845819875721L /* pi/4 */
M_1_PI 0.318309886183790671537767526745028724L /* 1/pi */
M_2_PI 0.636619772367581343075535053490057448L /* 2/pi */
M_2_SQRTPI 1.128379167095512573896158903121545172L /* 2/sqrt(pi) */
M_SQRT2 1.414213562373095048801688724209698079L /* sqrt(2) */
M_SQRT1_2 0.707106781186547524400844362104849039L /* 1/sqrt(2) */
-- snip --
On a 2nd thought... maybe we should define these constants via C99
hexfloat to make sure the last bits are OK...
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) [email protected]
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
diff -r -u original/src/cmd/ksh93/include/defs.h
build_numconstants/src/cmd/ksh93/include/defs.h
--- src/cmd/ksh93/include/defs.h 2013-08-12 16:31:56.000000000 +0200
+++ src/cmd/ksh93/include/defs.h 2013-08-19 22:24:21.258321372 +0200
@@ -423,6 +423,7 @@
extern char *sh_mactrim(Shell_t*,char*,int);
extern int sh_macexpand(Shell_t*,struct argnod*,struct
argnod**,int);
extern bool sh_macfun(Shell_t*,const char*,int);
+Namval_t *sh_get_arith_constant(Shell_t *, char *);
extern void sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*);
extern void *sh_macopen(Shell_t*);
extern char *sh_macpat(Shell_t*,struct argnod*,int);
diff -r -u original/src/cmd/ksh93/sh/arith.c
build_numconstants/src/cmd/ksh93/sh/arith.c
--- src/cmd/ksh93/sh/arith.c 2013-08-12 16:43:47.000000000 +0200
+++ src/cmd/ksh93/sh/arith.c 2013-08-19 22:29:29.156356354 +0200
@@ -59,6 +59,79 @@
"?",
};
+Namval_t *sh_get_arith_constant(Shell_t *shp, char *cp)
+{
+ Namval_t *np;
+ char *ld;
+ char saved_ld;
+ const char *prefix = NULL;
+
+ ld = strrchr(cp, '.');
+ if (!ld)
+ return (0);
+ saved_ld = *ld;
+ *ld = '\0';
+ np = nv_open(cp, shp->var_tree, NV_VARNAME|NV_NOADD|NV_NOFAIL);
+ *ld = saved_ld;
+ if (!np)
+ return (NULL);
+
+ if(nv_isattr(np, NV_INTEGER))
+ {
+ if(nv_isattr(np, NV_LDOUBLE) == NV_LDOUBLE)
+ {
+ prefix = "LDBL";
+ }
+ else if(nv_isattr(np, NV_FLOAT) == NV_FLOAT)
+ {
+ prefix = "FLT";
+ }
+ else if(nv_isattr(np, NV_DOUBLE) == NV_DOUBLE)
+ {
+ prefix = "DBL";
+ }
+ else if(nv_isattr(np, NV_UINT64) == NV_UINT64)
+ {
+ prefix = "UINT64";
+ }
+ else if(nv_isattr(np, NV_UINT16) == NV_UINT16)
+ {
+ prefix = "UINT16";
+ }
+ else if(nv_isattr(np, NV_UNT32) == NV_UNT32)
+ {
+ prefix = "UINT32";
+ }
+ else if(nv_isattr(np, NV_INT64) == NV_INT64)
+ {
+ prefix = "INT64";
+ }
+ else if(nv_isattr(np, NV_INT16) == NV_INT16)
+ {
+ prefix = "INT16";
+ }
+ else if(nv_isattr(np, NV_INT32) == NV_INT32)
+ {
+ prefix = "INT32";
+ }
+ }
+
+ nv_close(np);
+
+ if (prefix)
+ {
+ char buff[256];
+ sprintf(buff, ".sh.mathconst.%s_%s", prefix, ld+1);
+ np = nv_open(buff, shp->var_tree
,NV_VARNAME|NV_NOADD|NV_NOFAIL);
+ }
+ else
+ {
+ np = NULL;
+ }
+
+ return (np);
+}
+
static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int
assign)
{
register int flag = lvalue->flag;
@@ -90,8 +163,14 @@
cp[flag] = d;
return(&FunNode);
}
- if(!np && assign)
- np = nv_open(cp,shp->var_tree,assign|NV_VARNAME);
+ if (!np)
+ {
+ if (assign)
+ np =
nv_open(cp,shp->var_tree,assign|NV_VARNAME);
+ else
+ np = sh_get_arith_constant(shp, cp);
+ }
+
cp[flag] = d;
if(!np)
return(0);
diff -r -u original/src/cmd/ksh93/sh/macro.c
build_numconstants/src/cmd/ksh93/sh/macro.c
--- src/cmd/ksh93/sh/macro.c 2013-07-31 22:08:40.000000000 +0200
+++ src/cmd/ksh93/sh/macro.c 2013-08-19 22:24:40.206242082 +0200
@@ -1349,6 +1349,11 @@
fcmbget(&LEN);
return(true);
}
+
+ if(!np && (flag&NV_NOADD))
+ {
+ np = sh_get_arith_constant(mp->shp, id);
+ }
}
if(np && (flag&NV_NOADD) && nv_isnull(np))
{
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers