Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.89k stars 538 forks source link

Bug in POSIX::strtod at Windows #7577

Closed p5pRT closed 19 years ago

p5pRT commented 19 years ago

Migrated from rt.perl.org#32316 (status was 'rejected')

Searchable as RT32316$

p5pRT commented 19 years ago

From Torsten.Werner@assyst-intl.com

Created by torsten-werner@assyst-intl.com

This is a bug report for perl from torsten-werner@​assyst-intl.com\, generated with the help of perlbug 1.35 running under perl v5.8.4.

----------------------------------------------------------------- Posix​::strtod at Windows has a problem if a large number of digits appears after decimal dot.

Example​: G​:\>perl   use POSIX qw( strtod );   print join('\, '\,strtod("12.45006789"))\, "\n"; ^D 12\, 9

G​:\>

Perl is able to create and handle this kind of numbers.

Just in the moment I use a own function. I post it inside a test program. It works for different decimal dots in different regional settings of Windows.

################ cut here #####################

use strict; use warnings;

BEGIN {   if ($^O eq 'MSWin32') {   require Win32​::TieRegistry;   } }

use POSIX qw( localeconv ); my $decimal = localeconv()->{decimal_point} || '.'; my $win_decimal=($^O eq 'MSWin32') ? $Win32​::TieRegistry​::Registry->{' \CUser\Control Panel\International\\sDecimal'} : undef;

sub strtod ($) {   local $_=shift;   my $dec_expr='';   my %chars;   DECIMALS​: foreach my $char ($decimal\, $win_decimal) {   next DECIMALS if exists $chars{$char};   $dec_expr.=sprintf("\\x%x"\,ord($char)) if defined $char;   $chars{$char}=1;   };   $dec_expr="[$dec_expr]";   $dec_expr=qr/$dec_expr/;   # replace ".123" by "0.123"\, the regexp for numbers is easier so​:   s/^([+-]{0\,1})$dec_expr/${1}0$decimal/;   # find the leading number in 123.456 and 0.123456e3 notation​:   m/^((?-xism​:[+-]{0\,1}\d+(?-xism​:$dec_expr\d+){0\,1}(?i-xsm​:e[+-]{0\,1} \d+){0\,1}){0\,1})(.*)$/;   my $num=$1 ? $1 : 0;   my $no_num=$2 ? $2 : '';   return ($num\,length($no_num)) if wantarray;   return $num; }

sub show($) {   my $string=shift;   my ($num\, $no_num)=strtod($string);   print "String​: '$string' num​: '$num'\, no_num​: '$no_num'\n"; }

show 123 + 0.4560056789; show "123\,456.Hello"; show "Hallo"; show "-123"; show "-123."; show "+123"; show "+123."; show "+.2"; show ".2"; show "-.2"; show ".2e"; show ".2e3"; show ".2e.2"; show ".2e-.2"; show ".2E-2"; show "-.2e-.2"; show "-.2e+2"; show "-.2e+.2";

############## cut here ################

Perl Info ``` Flags: category=library severity=medium Site configuration information for perl v5.8.4: Configured by ActiveState at Tue Jun 1 11:52:09 2004. Summary of my perl5 (revision 5 version 8 subversion 4) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -Gf -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HASH_SEED -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX', optimize='-MD -Zi -DNDEBUG -O1', cppflags='-DWIN32' ccversion='', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE" -machine:x86' libpth=C:\PROGRA~1\MICROS~3\VC98\lib libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib gnulibc_version='undef' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE" -machine:x86' Locally applied patches: ACTIVEPERL_LOCAL_PATCHES_ENTRY 22751 Update to Test.pm 1.25 21540 Fix backward-compatibility issues in if.pm @INC for perl v5.8.4: C:/Perl/lib C:/Perl/site/lib . Environment for perl v5.8.4: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH=/usr/lib:/usr/X11R6/lib LOGDIR (unset) PATH=C:\PROGRA~1\Oracle\Ora920\bin;C:\PROGRA~1\Oracle\Ora817\bin;C: \Programme\Oracle\jre\1.3.1\bin;C:\Programme\Oracle\jre\1.1.8\bin;C: \Programme\Oracle\jre\1.1.7\bin;C:\Tcl\bin;C:\Perl\bin\;C: \WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C: \PROGRA~1\GEMEIN~1\SONICS~1\;C: \Programme\Hummingbird\Connectivity\9.00\Accessories\;C:\SFU\common\;C: \Programme\Gemeinsame Dateien\Autodesk Shared\;C:\Programme\WinCvs 1.3\CVSNT;C:\programme\SWIG-1.3.22;C:\Programme\Gemeinsame Dateien\GTK\2.0\bin;C:\Programme\Microsoft Visual Studio\Common\Tools\WinNT;C:\Programme\Microsoft Visual Studio\Common\MSDev98\Bin;C:\Programme\Microsoft Visual Studio\Common\Tools;C:\Programme\Microsoft Visual Studio\VC98\bin PERLDB_OPTS=RemotePort=127.0.0.1:2000 PERL_BADLANG (unset) SHELL (unset) ```
p5pRT commented 19 years ago

From @steve-m-hay

Torsten.Werner@​assyst-intl.com (via RT) wrote​:

Posix​::strtod at Windows has a problem if a large number of digits appears after decimal dot.

Example​: G​:\>perl use POSIX qw( strtod ); print join('\, '\,strtod("12.45006789"))\, "\n"; ^D 12\, 9

Works fine for me​:

C​:\Temp>perl -MPOSIX -e "print join('\, '\,POSIX​::strtod('12.45006789'));" 12.45006789\, 0

Just in the moment I use a own function. I post it inside a test program. It works for different decimal dots in different regional settings of Windows.

"Different decimal dots" could be the key there\, rather than the large number of digits after the decimal dot -- you're probably running in a locale other than English\, and that may be what's confusing POSIX​::strtod(). For example\, if I use a "\," instead of a "." in the number then I get the same output as you​:

C​:\Temp>perl -MPOSIX -e "print join('\, '\,POSIX​::strtod('12\,45006789'));" 12\, 9

However\, the POSIX​::strtod() docs do say that it should respect any POSIX​::setlocale() setting\, and if I change my locale to German then it does indeed work​:

C​:\Temp>perl -MPOSIX -e "setlocale(LC_ALL\, 'German'); print join('\, '\,POSIX​::strtod('12\,45006789'));" 12\,45006789\, 0

So perhaps you just need to set the locale appropriately?

- Steve


This email has been scanned for viruses and content by the Radan Computational Webshield Appliances.

p5pRT commented 19 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 19 years ago

From Torsten.Werner@assyst-intl.com

Hello\, you are right. With proper setlocale it works. Sorry for confusing. Torsten

 
  "Steve Hay via
  RT" To​: Torsten.Werner@​assyst-intl.com
  \<perlbug-followup cc​:
  @​perl.org> Subject​: Re​: [perl #32316] Bug in POSIX​::strtod at Windows
 
  04.11.2004 11​:47
  Please respond to
  perlbug-followup
 
 

Torsten.Werner@​assyst-intl.com (via RT) wrote​:

Posix​::strtod at Windows has a problem if a large number of digits appears after decimal dot.

Example​: G​:\>perl use POSIX qw( strtod ); print join('\, '\,strtod("12.45006789"))\, "\n"; ^D 12\, 9

Works fine for me​:

C​:\Temp>perl -MPOSIX -e "print join('\, '\,POSIX​::strtod('12.45006789'));" 12.45006789\, 0

Just in the moment I use a own function. I post it inside a test program. It works for different decimal dots in different regional settings of Windows.

"Different decimal dots" could be the key there\, rather than the large number of digits after the decimal dot -- you're probably running in a locale other than English\, and that may be what's confusing POSIX​::strtod(). For example\, if I use a "\," instead of a "." in the number then I get the same output as you​:

C​:\Temp>perl -MPOSIX -e "print join('\, '\,POSIX​::strtod('12\,45006789'));" 12\, 9

However\, the POSIX​::strtod() docs do say that it should respect any POSIX​::setlocale() setting\, and if I change my locale to German then it does indeed work​:

C​:\Temp>perl -MPOSIX -e "setlocale(LC_ALL\, 'German'); print join('\, '\,POSIX​::strtod('12\,45006789'));" 12\,45006789\, 0

So perhaps you just need to set the locale appropriately?

- Steve


This email has been scanned for viruses and content by the Radan Computational Webshield Appliances.

p5pRT commented 19 years ago

@iabyn - Status changed from 'open' to 'rejected'