[ksh93-integration-discuss] C99 "hexfloat" support via "typeset -X" ...

Roland Mainz roland.mainz at nrubsig.org
Wed Feb 6 20:08:45 PST 2008


Hi!

----

Attached is a small patch ("ksh93_c99_hexfloat_support001.txt") which
adds support for representing floating-point values as "[-]0xh.hhhhp+d"
(the same as C99/printf(3c) uses for "%a") when the shell is converting
the values to strings (e.g. $ print ${value} # or via $ export value #).
The idea is the same as the "typeset" option for scientific notation
(-E) except that the new format avoids the base16--->base10 rounding
errors and doesn't require going through the "printf" builtin for each
value (which improves performance and simplifies communication between
scripts a bit).

Example usage:
$ typeset -X foo
$ foo=0.5
$ print -- "$foo"
0x1.0000000000p-01
$ export foo
$ export | fgrep foo
foo=0x1.0000000000p-01

Comments/ideas/suggestions/rants/etc. welcome...

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.mainz at nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 7950090
 (;O/ \/ \O;)
-------------- next part --------------
Index: src/lib/libshell/sparcv9/include/ast/nval.h
===================================================================
--- src/lib/libshell/sparcv9/include/ast/nval.h	(revision 946)
+++ src/lib/libshell/sparcv9/include/ast/nval.h	(working copy)
@@ -174,6 +174,7 @@
 #define NV_UNSIGN	(NV_LTOU)	/* for unsigned quantities */
 #define NV_DOUBLE	(NV_ZFILL)	/* for floating point */
 #define NV_EXPNOTE	(NV_LJUST)	/* for scientific notation */
+#define NV_HEXFLOAT	(NV_BINARY)	/* for C99 base16 float notation */
 
 /*  options for nv_open */
 
Index: src/lib/libshell/common/include/nval.h
===================================================================
--- src/lib/libshell/common/include/nval.h	(revision 946)
+++ src/lib/libshell/common/include/nval.h	(working copy)
@@ -165,6 +165,7 @@
 #define NV_UNSIGN	(NV_LTOU)	/* for unsigned quantities */
 #define NV_DOUBLE	(NV_ZFILL)	/* for floating point */
 #define NV_EXPNOTE	(NV_LJUST)	/* for scientific notation */
+#define NV_HEXFLOAT	(NV_BINARY)	/* for C99 base16 float notation */
 
 /*  options for nv_open */
 
Index: src/lib/libshell/common/bltins/typeset.c
===================================================================
--- src/lib/libshell/common/bltins/typeset.c	(revision 946)
+++ src/lib/libshell/common/bltins/typeset.c	(working copy)
@@ -218,11 +218,14 @@
 					break;
 				}
 			case 'F':
+			case 'X':
 				if(!opt_info.arg || (tdata.argnum = opt_info.num) <0)
 					tdata.argnum = 10;
 				isfloat = 1;
 				if(n=='E')
 					flag |= NV_EXPNOTE;
+				if(n=='X')
+					flag |= NV_HEXFLOAT;
 				break;
 			case 'b':
 				flag |= NV_BINARY;
@@ -960,7 +963,7 @@
 		tp->prefix = nv_name(tp->tp);
 #endif /* SHOPT_TYPEDEF */
 	if(flag&NV_INTEGER)
-		tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE);
+		tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT);
 	namec = nv_scan(root,nullscan,(void*)tp,tp->scanmask,flag);
 	argv = tp->argnam  = (char**)stakalloc((namec+1)*sizeof(char*));
 	namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag);
Index: src/lib/libshell/common/data/builtins.c
===================================================================
--- src/lib/libshell/common/data/builtins.c	(revision 946)
+++ src/lib/libshell/common/data/builtins.c	(working copy)
@@ -1607,6 +1607,9 @@
 "[E]#?[n:=10?Floating point number represented in scientific notation. "
 	"\an\a specifies the number of significant figures when the "
 	"value is expanded.]"
+"[X]#?[n:=10?Floating point number represented in hexadecimal notation. "
+	"\an\a specifies the number of significant figures when the "
+	"value is expanded.]"
 "[F]#?[n:=10?Floating point.  \an\a is the number of places after the "
 	"decimal point when the value is expanded.]"
 "[H?Hostname mapping.  Each \aname\a holds a native pathname.  Assigning a "
Index: src/lib/libshell/common/data/options.c
===================================================================
--- src/lib/libshell/common/data/options.c	(revision 946)
+++ src/lib/libshell/common/data/options.c	(working copy)
@@ -128,6 +128,7 @@
 	{"-ttagged",	NV_TAGGED},
 	{"-llong",	(NV_INTEGER|NV_DOUBLE|NV_LONG)},
 	{"-Eexponential",(NV_INTEGER|NV_DOUBLE|NV_EXPNOTE)},
+	{"-Xhexfloat",	(NV_INTEGER|NV_DOUBLE|NV_HEXFLOAT)},
 	{"-Ffloat",	(NV_INTEGER|NV_DOUBLE)},
 	{"-llong",	(NV_INTEGER|NV_LONG)},
 	{"-sshort",	(NV_INTEGER|NV_SHORT)},
Index: src/lib/libshell/common/sh/nvtree.c
===================================================================
--- src/lib/libshell/common/sh/nvtree.c	(revision 946)
+++ src/lib/libshell/common/sh/nvtree.c	(working copy)
@@ -315,7 +315,7 @@
 			 * with E attribute from being given the F
 			 * attribute as well
 			*/
-			if(val==(NV_INTEGER|NV_DOUBLE) && (attr&NV_EXPNOTE))
+			if(val==(NV_INTEGER|NV_DOUBLE) && (attr&(NV_EXPNOTE|NV_HEXFLOAT)))
 				continue;
 			if(val&NV_INTEGER)
 				mask |= NV_DOUBLE;
Index: src/lib/libshell/common/sh/name.c
===================================================================
--- src/lib/libshell/common/sh/name.c	(revision 946)
+++ src/lib/libshell/common/sh/name.c	(working copy)
@@ -1351,7 +1351,7 @@
 	if((flag&NV_DOUBLE) && (flag&NV_INTEGER))
 	{
 		/* export doubles as integers for ksh88 compatibility */
-		stakputc(c+(flag&~(NV_DOUBLE|NV_EXPNOTE)));
+		stakputc(c+(flag&~(NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT)));
 	}
 	else
 	{
@@ -1376,7 +1376,7 @@
 	if((flag&NV_DOUBLE) && (flag&NV_INTEGER))
 	{
 		/* export doubles as integers for ksh88 compatibility */
-		*ap->attval++ = ' '+(flag&~(NV_DOUBLE|NV_EXPNOTE));
+		*ap->attval++ = ' '+(flag&~(NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT));
 		*ap->attval = ' ';
 	}
 	else
@@ -1875,7 +1875,9 @@
 			if(nv_isattr(np,NV_LONG))
 			{
 				ld = *up->ldp;
-				if(nv_isattr (np,NV_EXPNOTE))
+				if(nv_isattr (np,NV_HEXFLOAT))
+					format = "%.*La";
+				else if(nv_isattr (np,NV_EXPNOTE))
 					format = "%.*Lg";
 				else
 					format = "%.*Lf";
@@ -1884,7 +1886,9 @@
 			else
 			{
 				d = *up->dp;
-				if(nv_isattr (np,NV_EXPNOTE))
+				if(nv_isattr (np,NV_HEXFLOAT))
+					format = "%.*a";
+				else if(nv_isattr (np,NV_EXPNOTE))
 					format = "%.*g";
 				else
 					format = "%.*f";
Index: src/lib/libshell/common/sh/nvdisc.c
===================================================================
--- src/lib/libshell/common/sh/nvdisc.c	(revision 946)
+++ src/lib/libshell/common/sh/nvdisc.c	(working copy)
@@ -269,7 +269,7 @@
 			nv_unset(SH_VALNOD);
 		}
 		if(flags&NV_INTEGER)
-			nv_onattr(SH_VALNOD,(flags&(NV_INTEGER|NV_LONG|NV_DOUBLE|NV_EXPNOTE|NV_SHORT)));
+			nv_onattr(SH_VALNOD,(flags&(NV_INTEGER|NV_LONG|NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT|NV_SHORT)));
 		nv_putval(SH_VALNOD, val, (flags&NV_INTEGER)?flags:NV_NOFREE);
 	}
 	else
Index: src/lib/libshell/sparc/include/ast/nval.h
===================================================================
--- src/lib/libshell/sparc/include/ast/nval.h	(revision 946)
+++ src/lib/libshell/sparc/include/ast/nval.h	(working copy)
@@ -174,6 +174,7 @@
 #define NV_UNSIGN	(NV_LTOU)	/* for unsigned quantities */
 #define NV_DOUBLE	(NV_ZFILL)	/* for floating point */
 #define NV_EXPNOTE	(NV_LJUST)	/* for scientific notation */
+#define NV_HEXFLOAT	(NV_BINARY)	/* for C99 base16 float notation */
 
 /*  options for nv_open */
 
Index: src/lib/libshell/i386/include/ast/nval.h
===================================================================
--- src/lib/libshell/i386/include/ast/nval.h	(revision 946)
+++ src/lib/libshell/i386/include/ast/nval.h	(working copy)
@@ -174,6 +174,7 @@
 #define NV_UNSIGN	(NV_LTOU)	/* for unsigned quantities */
 #define NV_DOUBLE	(NV_ZFILL)	/* for floating point */
 #define NV_EXPNOTE	(NV_LJUST)	/* for scientific notation */
+#define NV_HEXFLOAT	(NV_BINARY)	/* for C99 base16 float notation */
 
 /*  options for nv_open */
 
Index: src/lib/libshell/amd64/include/ast/nval.h
===================================================================
--- src/lib/libshell/amd64/include/ast/nval.h	(revision 946)
+++ src/lib/libshell/amd64/include/ast/nval.h	(working copy)
@@ -174,6 +174,7 @@
 #define NV_UNSIGN	(NV_LTOU)	/* for unsigned quantities */
 #define NV_DOUBLE	(NV_ZFILL)	/* for floating point */
 #define NV_EXPNOTE	(NV_LJUST)	/* for scientific notation */
+#define NV_HEXFLOAT	(NV_BINARY)	/* for C99 base16 float notation */
 
 /*  options for nv_open */
 


More information about the ksh93-integration-discuss mailing list