Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in POSIX::strtod at Windows #7577

Closed
p5pRT opened this issue Nov 4, 2004 · 5 comments
Closed

Bug in POSIX::strtod at Windows #7577

p5pRT opened this issue Nov 4, 2004 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 4, 2004

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

Searchable as RT32316$

@p5pRT
Copy link
Author

p5pRT commented Nov 4, 2004

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
Copy link
Author

p5pRT commented Nov 4, 2004

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
Copy link
Author

p5pRT commented Nov 4, 2004

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

@p5pRT
Copy link
Author

p5pRT commented Nov 5, 2004

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
Copy link
Author

p5pRT commented Nov 6, 2004

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant