Ienup Sung wrote:
[snip]
> > Something is going wrong here (CC:'ing the i18n-discuss at opensolaris.org
> > in the hope that Ienup may know what may cause this...) ... any ideas
> > where this bug may hide ?
> 
> I downloaded ast-ksh.2006-06-30.tgz and INIT.2006-06-30.tgz this afternoon
> and traced the source with C and en_US locales at Solaris 10 and found
> the reason is due to there is a bug in strtold() at lib/libast/sfio/sfstrtof.h
> especially the line 362 where it assumes that the thousand separator
> character of the current locale is a valid part of a double number regardless
> of its position, i.e., it assumes that the comma argument separator at
> the pow(1.0,Inf) expression as a part of the first input argument, "1.0":
> 
>          n = 0;
>          m = 0;
>          for (;;)
>          {
>                  if (c >= '0' && c <= '9')
>                  {
>                          digits++;
>                          n = (n << 3) + (n << 1) + (c - '0');
>                          if (n >= ((~((S2F_batch)0)) / 10) && part < 
> elementsof(p
> arts))
>                          {
>                                  parts[part].batch = n;
>                                  n = 0;
>                                  parts[part].digits = digits;
>                                  part++;
>                          }
>                  }
>                  else if (m && (digits - m) != 3)
>                          break;
>                  else if (c == decimal)
>                  {
>                          decimal = -1;
>                          m = 0;
>                          fraction = digits;
>                  }
>                  else if (c != thousand)    /* <--<<< */
>                          break;
>                  else if (!(m = digits))
>                          break;
>                  c = GET(s);
>          }
> 
> and thus the above consumes the ',' and move the expression string pointer
> one more character than necessary. The locales that don't have this issue
> would be the ones that the thousand separater is defined in their
> locale database as -1. For instance:
> 
>         $ env LC_ALL=C locale -k thousands_sep
>         thousands_sep=""
>         $ env LC_ALL=en_US.UTF-8 locale -k thousands_sep
>         thousands_sep=""
>         $ env LC_ALL=ja_JP.UTF-8 locale -k thousands_sep
>         thousands_sep=","
>         $ env LC_ALL=de_DE.UTF-8 locale -k thousands_sep
>         thousands_sep="."
>         $
> 
> And so if you replace the line 362 to the following expression, then,
> the problem appears go away:
> 
>                  else if (c != thousand || (c == thousand && decimal == -1))
> 
> For instance:
> 
>         $ export LC_ALL=de_DE.UTF-8 ; echo $((pow(1,0,Inf)))
>         NaN
>         $ export LC_ALL=ja_JP.UTF-8 ; echo $((pow(1.0,Inf)))
>         NaN

Thank you very much for the digging&explanation... :-)

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.mainz at nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 7950090
 (;O/ \/ \O;)

Reply via email to