zsh-workers
 help / color / mirror / code / Atom feed
* LC_NUMERIC=fr_FR and floating point arithmetics
@ 2003-02-24 17:45 Stephane CHAZELAS
  2003-03-10  8:58 ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Stephane CHAZELAS @ 2003-02-24 17:45 UTC (permalink / raw)
  To: Zsh hackers list

$ LC_NUMERIC=fr_FR ksh93 -c 'float a=1; echo $(( a / 3 ))'
0,333333333333
$ LC_NUMERIC=fr_FR zsh -c 'float a=1; echo $(( a / 3 ))'
0,33333333333333331.

zsh seems to assume that "." is the decimal separator which is
not correct in a french locale.

I agree this is confusing. A ksh93 script such as
echo $(( 1. / 3 ))

won't work under french locale.
(must be echo $(( 1, / 3 )) )

(tried with zsh 4.1.0-dev-7)

-- 
Stéphane


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: LC_NUMERIC=fr_FR and floating point arithmetics
  2003-02-24 17:45 LC_NUMERIC=fr_FR and floating point arithmetics Stephane CHAZELAS
@ 2003-03-10  8:58 ` Oliver Kiddle
  2003-03-10 19:25   ` Zefram
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2003-03-10  8:58 UTC (permalink / raw)
  To: Stephane CHAZELAS; +Cc: Zsh hackers list

On 24 Feb, Stephane CHAZELAS wrote:
> $ LC_NUMERIC=fr_FR ksh93 -c 'float a=1; echo $(( a / 3 ))'
> 0,333333333333
> $ LC_NUMERIC=fr_FR zsh -c 'float a=1; echo $(( a / 3 ))'
> 0,33333333333333331.
>
> zsh seems to assume that "." is the decimal separator which is
> not correct in a french locale.
> 
> I agree this is confusing. A ksh93 script such as
> echo $(( 1. / 3 ))
>
> won't work under french locale.
> (must be echo $(( 1, / 3 )) )

Which is worse in my opinion. $(( 1.1 )) really ought to be interpreted
as a 1 point 1 regardless of locale - it is otherwise impossible to use
decimals in portable shell scripts.

If we didn't have backward and ksh compatibility to consider, I would
be inclined to say that $a for floats and $(( ... )) should always use
the C locale and anyone wanting locale specific output could use printf
(see below) (implementing this is easy; just save the LC_NUMERIC locale
in convfloat()).

But keeping locale handling in output means that scalar parameters
can't be reused in a calculation. And making math evaluation accept
either `.' or whatever the locale dictates is not easy when you
consider that a comma in math evaluation is used as a separator:
  (( a=1, 3.4 ))
Also, because we allow this:
  % a='3 + 4'
  % echo $(( a ))
  7
you can't just interpret the comma in a parameter expansion. So I can't
think of any solution except limiting math evaluation to the C locale.

So what can we do?

I did a grep for mon_decimal_point in /usr/share/i18n/locales to see
if any other characters are used as decimal separators. It indicates
that Portugal use `$' as their decimal separator. Seems weird. Apart
from that it is , or . for the rest of the world except Burkina Faso
who apparently use something outside the normal ASCII range.

Currently, a bug prevents locale handling for printf (on at least some
platforms). The bug causing this is in math.c where it does:
	prev_locale = setlocale(LC_NUMERIC, NULL);
	setlocale(LC_NUMERIC, "POSIX");
The second setlocale call clobbers prev_locale - we have to use
dupstring(). The patch fixes this.

Oliver

diff -ur zsh-latest/Src/math.c localeprob2/Src/math.c
--- zsh-latest/Src/math.c	2002-12-19 10:58:19.000000000 +0000
+++ localeprob2/Src/math.c	2003-03-09 01:13:18.000000000 +0000
@@ -399,12 +399,12 @@
 		    /* it's a float */
 		    yyval.type = MN_FLOAT;
 #ifdef USE_LOCALE
-		    prev_locale = setlocale(LC_NUMERIC, NULL);
+		    prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
 		    setlocale(LC_NUMERIC, "POSIX");
 #endif
 		    yyval.u.d = strtod(ptr, &nptr);
 #ifdef USE_LOCALE
-		    setlocale(LC_NUMERIC, prev_locale);
+		    if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
 #endif
 		    if (ptr == nptr || *nptr == '.') {
 			zerr("bad floating point constant", NULL, 0);


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: LC_NUMERIC=fr_FR and floating point arithmetics
  2003-03-10  8:58 ` Oliver Kiddle
@ 2003-03-10 19:25   ` Zefram
  2003-03-11 10:35     ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Zefram @ 2003-03-10 19:25 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Stephane CHAZELAS, Zsh hackers list

Oliver Kiddle wrote:
>But keeping locale handling in output means that scalar parameters
>can't be reused in a calculation.

Numeric output should by default be in the input format (C locale)
so that it can be reused in the expected manner.  If printf is not
sufficient for rendering numbers in human format, we could add an
output-using-locale flag to the output format specification syntax of
$(()) -- there's already syntax to select the radix to use on output.

-zefram


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: LC_NUMERIC=fr_FR and floating point arithmetics
  2003-03-10 19:25   ` Zefram
@ 2003-03-11 10:35     ` Oliver Kiddle
  2003-03-12  3:32       ` Philippe Troin
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Kiddle @ 2003-03-11 10:35 UTC (permalink / raw)
  To: Zsh workers

Zefram wrote:
> 
> Numeric output should by default be in the input format (C locale)
> so that it can be reused in the expected manner.

Okay, this patch makes it do that.

> If printf is not
> sufficient for rendering numbers in human format, we could add an
> output-using-locale flag to the output format specification syntax of
> $(()) -- there's already syntax to select the radix to use on output.

It would possibly be more useful for $a than $(()) because that is where
all the typeset -F/-E stuff applies. I'll wait and see if there is
demand and if so, a parameter expansion flag could also be added (L and
l are gone along with most of the rest of the alphabet so we'd need to
think of a suitable free letter). If ksh keeps it's current behaviour, a
KSH_something option could perhaps be used.

I consider this patch a bug fix which would imply that I should apply it
to 4.0 but 4.0 doesn't have printf and hence has no way to output floats
in the current locale. I could backport printf, leave the patch out of
4.0 or do something else. Any thoughts?

Note also, that there is no way to input numbers with locale
conventions. If there is demand for a way to do this, we could perhaps
add an option to read so that typeset -F num; read num would do this but
lose math evaluation. Or perhaps add the facility somewhere else.

Oliver

Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.69
diff -u -r1.69 params.c
--- Src/params.c	31 Oct 2002 18:32:40 -0000	1.69
+++ Src/params.c	11 Mar 2003 10:00:10 -0000
@@ -3417,6 +3417,7 @@
 convfloat(double dval, int digits, int flags, FILE *fout)
 {
     char fmt[] = "%.*e";
+    char *prev_locale, *ret;
 
     /*
      * The difficulty with the buffer size is that a %f conversion
@@ -3451,16 +3452,24 @@
 	    digits--;
 	}
     }
+#ifdef USE_LOCALE
+    prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
+    setlocale(LC_NUMERIC, "POSIX");
+#endif
     if (fout) {
 	fprintf(fout, fmt, digits, dval);
-	return NULL;
+	ret = NULL;
     } else {
 	VARARR(char, buf, 512 + digits);
 	sprintf(buf, fmt, digits, dval);
 	if (!strchr(buf, 'e') && !strchr(buf, '.'))
 	    strcat(buf, ".");
-	return dupstring(buf);
+	ret = dupstring(buf);
     }
+#ifdef USE_LOCALE
+    if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+#endif
+    return ret;
 }
 
 /* Start a parameter scope */


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: LC_NUMERIC=fr_FR and floating point arithmetics
  2003-03-11 10:35     ` Oliver Kiddle
@ 2003-03-12  3:32       ` Philippe Troin
  2003-03-12  8:30         ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Philippe Troin @ 2003-03-12  3:32 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

Oliver Kiddle <okiddle@yahoo.co.uk> writes:

> Index: Src/params.c
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Src/params.c,v
> retrieving revision 1.69
> diff -u -r1.69 params.c
> --- Src/params.c	31 Oct 2002 18:32:40 -0000	1.69
> +++ Src/params.c	11 Mar 2003 10:00:10 -0000
> @@ -3417,6 +3417,7 @@
>  convfloat(double dval, int digits, int flags, FILE *fout)
>  {
>      char fmt[] = "%.*e";
> +    char *prev_locale, *ret;
>  
>      /*
>       * The difficulty with the buffer size is that a %f conversion
> @@ -3451,16 +3452,24 @@
>  	    digits--;
>  	}
>      }
> +#ifdef USE_LOCALE
> +    prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
> +    setlocale(LC_NUMERIC, "POSIX");
> +#endif
>      if (fout) {
>  	fprintf(fout, fmt, digits, dval);
> -	return NULL;
> +	ret = NULL;
>      } else {
>  	VARARR(char, buf, 512 + digits);
>  	sprintf(buf, fmt, digits, dval);
>  	if (!strchr(buf, 'e') && !strchr(buf, '.'))
>  	    strcat(buf, ".");
> -	return dupstring(buf);
> +	ret = dupstring(buf);
>      }
> +#ifdef USE_LOCALE
> +    if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
> +#endif
> +    return ret;
>  }
>  
>  /* Start a parameter scope */

Aren't you leaking a copy of the current locale (via dupstring())
every time?

Phil.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: LC_NUMERIC=fr_FR and floating point arithmetics
  2003-03-12  3:32       ` Philippe Troin
@ 2003-03-12  8:30         ` Oliver Kiddle
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Kiddle @ 2003-03-12  8:30 UTC (permalink / raw)
  To: Philippe Troin; +Cc: Zsh workers

Philippe Troin wrote:
> 
> Aren't you leaking a copy of the current locale (via dupstring())
> every time?

dupstring() calls zhalloc() to allocate memory instead of zalloc()
(unlike ztrdup()). So the memory should be freed the next time popheap()
is called (which I think is done for each command line). The comment at
the top of mem.c is what I'm basing this on. So I've always assumed that
zalloc should only be used for things which need to persist from one
command to the next, where realloc() is needed or where a large chunk of
memory is needed.

Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-03-12  8:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-24 17:45 LC_NUMERIC=fr_FR and floating point arithmetics Stephane CHAZELAS
2003-03-10  8:58 ` Oliver Kiddle
2003-03-10 19:25   ` Zefram
2003-03-11 10:35     ` Oliver Kiddle
2003-03-12  3:32       ` Philippe Troin
2003-03-12  8:30         ` Oliver Kiddle

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).