Discussion:
[ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
Tina Harriott
2013-08-19 13:57:15 UTC
Permalink
The concept of bool b; (( b.true )) reminds me of java, python and
other programming languages which tie limits and constants to a
specific type instead of littering the global namespace with the
definitions (like C).

Could the numeric types, i.e. typeset -i/-E have a similar
functionality like b.true to access the minimum, maximum, epsilon, ...
values?

For example:

typeset -lE i; (( i.MIN )) would be the equivalent to C's LDBL_MIN
typeset -lE i; (( i.MAX )) would be the equivalent to C's LDBL_MAX
typeset -lE i; (( i.EPSILON )) would be the equivalent to C's LDBL_EPSILON
typeset -lE i; (( i.MAX_10_EXP )) would be the equivalent to C's LDBL_MAX_10_EXP
typeset -sE i; (( i.MIN )) would be the equivalent to C's FLT_MIN
typeset -sE i; (( i.MAX )) would be the equivalent to C's FLT_MAX
typeset -sE i; (( i.EPSILON )) would be the equivalent to C's FLT_EPSILON
typeset -sE i; (( i.MAX_10_EXP )) would be the equivalent to C's FLT_MAX_10_EXP

Tina

---------- Forwarded message ----------
From: Wendy Lin <wendlin1974 at gmail.com>
Date: 12 August 2013 08:53
Subject: Re: [ast-developers] "${_Bool.true}" not working... / was:
Re: AT&T Software Technology ast alpha software download update
To: Roland Mainz <roland.mainz at nrubsig.org>, David Korn <dgk at research.att.com>
Cc: ast-developers at research.att.com
the AT&T Software Technology ast alpha 2013-08-07 source release
has been posted to the download site
http://www.research.att.com/sw/download/alpha/
the package names and md5 checksums are
INIT 47f2073fae4b73fe5210cc4e287556ca
ast-open e6927faa687a2af8ee94431b793c08ac
ast-ksh 43b7379fdf573811c66f41ce231cbac0
the md5 sums should match the ones listed on the download page
[snip]
13-07-30 +An experimental change to each enumeration variable have subvariables
for each enumeration constant. ${enum.name} will expand to the
numerical value of the enumeration name associatied with enum.
-- snip --
$ ~/bin/ksh -o nounset -c 'print "${_Bool.true}"'
/home/test001/bin/ksh: _Bool.true: parameter not set
$ ~/bin/ksh -o nounset -c 'print "$((_Bool.true))"'
/home/test001/bin/ksh: _Bool.true: parameter not set
-- snip --
It works for me:
ksh -o nounset -c 'bool b ; print $((b.true))'
1


But there is still a bug left:

var.true/var.false don't work for array elements:
./arch/linux.i386-64/bin/ksh -o nounset -c 'bool -a b=( [4][5]=true )
; print $((b[4][5].true))'
./arch/linux.i386-64/bin/ksh: b[4][5].true: parameter not set
./arch/linux.i386-64/bin/ksh -o nounset -c 'bool -A b=( [lin]=true ) ;
print $((b[lin].true))'
./arch/linux.i386-64/bin/ksh: b[lin].true: parameter not set

Wendy
_______________________________________________
ast-developers mailing list
ast-developers at lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-developers
--
Tina Harriott - Women in Mathematics
Contact: tina.harriott.math at gmail.com
David Korn
2013-08-19 17:09:25 UTC
Permalink
Subject: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Tina Harriott
Could the numeric types, i.e. typeset -i/-E have a similar
functionality like b.true to access the minimum, maximum, epsilon, ...
values?
typeset -lE i; (( i.MIN )) would be the equivalent to C's LDBL_MIN
typeset -lE i; (( i.MAX )) would be the equivalent to C's LDBL_MAX
typeset -lE i; (( i.EPSILON )) would be the equivalent to C's LDBL_EPSILON
typeset -lE i; (( i.MAX_10_EXP )) would be the equivalent to C's LDBL_MAX_10_EXP
typeset -sE i; (( i.MIN )) would be the equivalent to C's FLT_MIN
typeset -sE i; (( i.MAX )) would be the equivalent to C's FLT_MAX
typeset -sE i; (( i.EPSILON )) would be the equivalent to C's FLT_EPSILON
typeset -sE i; (( i.MAX_10_EXP )) would be the equivalent to C's FLT_MAX_10_EXP
Tina
Interesting idea, but the implementation technique that I use for
types would be too inefficient in space for numbers.

I will put this on my list of possible extensions.

David Korn
dgk at research.att.com
Roland Mainz
2013-08-19 17:21:09 UTC
Permalink
Post by David Korn
Subject: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
Post by Tina Harriott
Could the numeric types, i.e. typeset -i/-E have a similar
functionality like b.true to access the minimum, maximum, epsilon, ...
values?
typeset -lE i; (( i.MIN )) would be the equivalent to C's LDBL_MIN
typeset -lE i; (( i.MAX )) would be the equivalent to C's LDBL_MAX
typeset -lE i; (( i.EPSILON )) would be the equivalent to C's LDBL_EPSILON
typeset -lE i; (( i.MAX_10_EXP )) would be the equivalent to C's LDBL_MAX_10_EXP
typeset -sE i; (( i.MIN )) would be the equivalent to C's FLT_MIN
typeset -sE i; (( i.MAX )) would be the equivalent to C's FLT_MAX
typeset -sE i; (( i.EPSILON )) would be the equivalent to C's FLT_EPSILON
typeset -sE i; (( i.MAX_10_EXP )) would be the equivalent to C's FLT_MAX_10_EXP
Interesting idea, but the implementation technique that I use for
types would be too inefficient in space for numbers.
Well... it would solve the issue I had with my .sh.math idea to store
the constants there - what happens if someone picks the wrong type for
a specific constant (e.g. uses .sh.math.FLT_MAX for a "typeset -l -E"
etc.) ... Tina's idea (derived from java, python and other similar
languages) solves the issue in a very clean and programmer-friendly
way...
Post by David Korn
I will put this on my list of possible extensions.
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 '.' ?

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Glenn Fowler
2013-08-19 18:03:25 UTC
Permalink
Post by Tina Harriott
The concept of bool b; (( b.true )) reminds me of java, python and
other programming languages which tie limits and constants to a
specific type instead of littering the global namespace with the
definitions (like C).
Could the numeric types, i.e. typeset -i/-E have a similar
functionality like b.true to access the minimum, maximum, epsilon, ...
values?
typeset -lE i; (( i.MIN )) would be the equivalent to C's LDBL_MIN
typeset -lE i; (( i.MAX )) would be the equivalent to C's LDBL_MAX
typeset -lE i; (( i.EPSILON )) would be the equivalent to C's LDBL_EPSILON
typeset -lE i; (( i.MAX_10_EXP )) would be the equivalent to C's LDBL_MAX_10_EXP
typeset -sE i; (( i.MIN )) would be the equivalent to C's FLT_MIN
typeset -sE i; (( i.MAX )) would be the equivalent to C's FLT_MAX
typeset -sE i; (( i.EPSILON )) would be the equivalent to C's FLT_EPSILON
typeset -sE i; (( i.MAX_10_EXP )) would be the equivalent to C's FLT_MAX_10_EXP
for { FLT INT UINT } could you list the possible names
e.g., ast_float.h currently misses FLT_EPSILON

thanks
Roland Mainz
2013-08-19 21:45:09 UTC
Permalink
Post by Glenn Fowler
Post by Tina Harriott
The concept of bool b; (( b.true )) reminds me of java, python and
other programming languages which tie limits and constants to a
specific type instead of littering the global namespace with the
definitions (like C).
Could the numeric types, i.e. typeset -i/-E have a similar
functionality like b.true to access the minimum, maximum, epsilon, ...
values?
typeset -lE i; (( i.MIN )) would be the equivalent to C's LDBL_MIN
typeset -lE i; (( i.MAX )) would be the equivalent to C's LDBL_MAX
typeset -lE i; (( i.EPSILON )) would be the equivalent to C's LDBL_EPSILON
typeset -lE i; (( i.MAX_10_EXP )) would be the equivalent to C's LDBL_MAX_10_EXP
typeset -sE i; (( i.MIN )) would be the equivalent to C's FLT_MIN
typeset -sE i; (( i.MAX )) would be the equivalent to C's FLT_MAX
typeset -sE i; (( i.EPSILON )) would be the equivalent to C's FLT_EPSILON
typeset -sE i; (( i.MAX_10_EXP )) would be the equivalent to C's FLT_MAX_10_EXP
for { FLT INT UINT } could you list the possible names
e.g., ast_float.h currently misses FLT_EPSILON
See http://lists.research.att.com/pipermail/ast-developers/2013q3/003198.html
... it has a prototype patch which works with $(( var.CONST )) and
${var.CONST} and has the list of constants which should be defined by
default.

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
David Korn
2013-08-19 18:10:19 UTC
Permalink
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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.

David Korn
dgk at research.att.com
Roland Mainz
2013-08-19 21:24:54 UTC
Permalink
Post by David Korn
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
-------------- next part --------------
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))
{
Roland Mainz
2013-08-20 00:37:01 UTC
Permalink
Post by Roland Mainz
Post by David Korn
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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
-- 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
-- snip --
# integer for $((i.MIN)) and $((i.MAX))
[snip]
Post by Roland Mainz
# float for $((i.MANT_DIG , i.MIN_EXP , i.MIN_10_EXP, i.MAX_EXP ,
[snip]
Post by Roland Mainz
-- snip --
-- snip --
[snip]
Post by Roland Mainz
-- snip --
On a 2nd thought... maybe we should define these constants via C99
hexfloat to make sure the last bits are OK...
Erm... David/Glenn: Can we chat this week about the code, please ? I
talked with Olga and she thinks ${var.CONST} (returning a C99 hexfloat
value) may be mandatory (together with [[ -v var.CONST ]] to test
whether the value is there) for same use cases. My idea to solve it
would be to use a hybrid approach... use a table and create the
|Namval_t *| nodes on the fly on the first access (that would avoid
any resource/startup time penalty and give us maximum flexibility).

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Tina Harriott
2013-08-20 12:58:22 UTC
Permalink
Post by Roland Mainz
Post by David Korn
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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
-- 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
-- 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 --
-- 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...
What exactly is a C99 hexfloat?

Tina
--
Tina Harriott - Women in Mathematics
Contact: tina.harriott.math at gmail.com
Tina Harriott
2013-08-21 16:11:26 UTC
Permalink
Post by Roland Mainz
Post by David Korn
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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
-- 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
-- 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 --
-- 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...
Roland, thank you for the patch. I like it, except that it requires
that constants have to be defined by hand, i.e. in each script again
and again. Could you implement an internal table with these constants
predefined, please?

Tina
--
Tina Harriott - Women in Mathematics
Contact: tina.harriott.math at gmail.com
Wendy Lin
2013-08-26 17:41:55 UTC
Permalink
Post by Roland Mainz
Post by David Korn
cc: ast-developers at lists.research.att.com
Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) constants?
--------
Post by Roland Mainz
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
-- 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
-- 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 --
-- 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...
2. The implementation is inconsistant in that ${!foo*} does not
expand all integer variables starting with foo to each of the
18 integer or 27 possible float suffices for integer and float
respectively.
Is it hard to fix this?

Wendy

Loading...