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

Math::BigFloat::fcmp() incorrect for +0E+0 #935

Closed
p5pRT opened this issue Dec 11, 1999 · 2 comments
Closed

Math::BigFloat::fcmp() incorrect for +0E+0 #935

p5pRT opened this issue Dec 11, 1999 · 2 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 11, 1999

Migrated from rt.perl.org#1880 (status was 'resolved')

Searchable as RT1880$

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 1999

From @tamias

Math​::BigFloat​::fcmp() incorrectly determines that 0 is greater than any
positive non-integer. This occurs because in BigFloat's representation of
0 (+0E+0) has an exponent of 0, while its representation of a non-integer
such as 0.9 (+9E-1) has a negative exponent. fcmp() compares the exponents
without noting that one of the operands is equal to 0.

# compare 2 values returns one of undef, <0, =0, >0
# returns undef if either or both input value are not numbers
sub fcmp #(fnum_str, fnum_str) return cond_code
{
  local($x, $y) = (fnorm($_[$[]),fnorm($_[$[+1]));
  if ($x eq "NaN" || $y eq "NaN") {
  undef;
  } else {
  ord($y) <=> ord($x)
  ||
  ( local($xm,$xe,$ym,$ye) = split('E', $x."E$y"),
  (($xe <=> $ye) * (substr($x,$[,1).'1') # <=== BUG!
  || Math​::BigInt​::cmp($xm,$ym))
  );
  }
}

I note the following in Math​::BigFloat's documentation​:

  BUGS

  The current version of this module is a preliminary version of the
  real thing that is currently (as of perl5.002) under development.

Is the "real thing" still under active development?

Perl Info


Site configuration information for perl 5.00503:

Configured by sting at Mon Jul 26 10:22:37 EDT 1999.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=irix, osvers=6.5, archname=IP32-irix
    uname='irix linguist 6.5 01221644 ip32 '
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='cc -n32', optimize='-O3', gccversion=
    cppflags='-D_BSD_TYPES -D_BSD_TIME -OPT:Olimit=0:space=ON -I/usr/local/include -DLANGUAGE_C'
    ccflags ='-D_BSD_TYPES -D_BSD_TIME -woff 1009,1110,1184 -OPT:Olimit=0:space=ON -I/usr/local/include -DLANGUAGE_C'
    stdchar='unsigned char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='cc -n32', ldflags ='-L/usr/local/lib -L/usr/linguist/lib -L/usr/local/lib32'
    libpth=/usr/local/lib /usr/lib32 /lib32 /lib /usr/lib /usr/linguist/lib
    libs=-lm
    libc=/usr/lib32/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-n32 -shared -L/usr/local/lib -L/usr/linguist/lib -L/usr/local/lib32'

Locally applied patches:
    


@INC for perl 5.00503:
    /usr/linguist/lib/perl5/5.00503/IP32-irix
    /usr/linguist/lib/perl5/5.00503
    /usr/linguist/lib/perl5/site_perl/5.005/IP32-irix
    /usr/linguist/lib/perl5/site_perl/5.005
    .


Environment for perl 5.00503:
    HOME=/usr/people/rjk
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/usr/linguist/bin:/usr/sbin:/usr/bsd:/sbin:/usr/bin/X11:/usr/local/bin:/usr/afsws/bin:/usr/etc:/usr/people/rjk/scripts:/usr/people/rjk/bin:.
    PERL_BADLANG (unset)
    SHELL=/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 1999

From @tamias

Here's a patch for Math​::BigFloat​::fcmp() to give correct results when one
of the operands is +0E+0. The patch to bigfltpm.t also fixes some minor
inconsistent formatting. Patched against 5.005_63.

I assume the answer to my question at the end is 'No'.

Ronald

*** lib/Math/BigFloat.pm.orig Tue Jul 20 17​:18​:00 1999
--- lib/Math/BigFloat.pm Thu Dec 16 00​:33​:59 1999
***************
*** 240,251 ****
  if ($x eq "NaN" || $y eq "NaN") {
  undef;
  } else {
  ord($y) <=> ord($x)
! ||
! ( local($xm,$xe,$ym,$ye) = split('E', $x."E$y"),
! (($xe <=> $ye) * (substr($x,$[,1).'1')
! || Math​::BigInt​::cmp($xm,$ym))
! );
  }
  }
 
--- 240,252 ----
  if ($x eq "NaN" || $y eq "NaN") {
  undef;
  } else {
+ local($xm,$xe,$ym,$ye) = split('E', $x."E$y");
+ if ($xm eq '+0' || $ym eq '+0') {
+ return $xm <=> $ym;
+ }
  ord($y) <=> ord($x)
! || ($xe <=> $ye) * (substr($x,$[,1).'1')
! || Math​::BigInt​::cmp($xm,$ym);
  }
  }
 
*** t/bigfltpm.t.orig Tue Sep 14 08​:55​:35 1999
--- t/bigfltpm.t Thu Dec 16 00​:39​:19 1999
***************
*** 9,15 ****
 
  $test = 0;
  $| = 1;
! print "1..358\n";
  while (<DATA>) {
  chop;
  if (s/^&//) {
--- 9,15 ----
 
  $test = 0;
  $| = 1;
! print "1..362\n";
  while (<DATA>) {
  chop;
  if (s/^&//) {
***************
*** 41,55 ****
  $try .= "0+\$x->fsqrt;";
  } else {
  $try .= "\$y = new Math​::BigFloat \"$args[1]\";";
! if ($f eq fcmp){
  $try .= "\$x <=> \$y;";
! }elsif ($f eq fadd){
  $try .= "\$x + \$y;";
! }elsif ($f eq fsub){
  $try .= "\$x - \$y;";
! }elsif ($f eq fmul){
  $try .= "\$x * \$y;";
! }elsif ($f eq fdiv){
  $try .= "\$x / \$y;";
  } else { warn "Unknown op"; }
  }
--- 41,55 ----
  $try .= "0+\$x->fsqrt;";
  } else {
  $try .= "\$y = new Math​::BigFloat \"$args[1]\";";
! if ($f eq "fcmp") {
  $try .= "\$x <=> \$y;";
! } elsif ($f eq "fadd") {
  $try .= "\$x + \$y;";
! } elsif ($f eq "fsub") {
  $try .= "\$x - \$y;";
! } elsif ($f eq "fmul") {
  $try .= "\$x * \$y;";
! } elsif ($f eq "fdiv") {
  $try .= "\$x / \$y;";
  } else { warn "Unknown op"; }
  }
***************
*** 271,276 ****
--- 271,280 ----
  +1​:-1​:1
  -1​:-1​:0
  +1​:+1​:0
+ -1.1​:0​:-1
+ +0​:-1.1​:1
+ +1.1​:+0​:1
+ +0​:+1.1​:-1
  +123​:+123​:0
  +123​:+12​:1
  +12​:+123​:-1

--

On Sun, Dec 12, 1999 at 02​:12​:25AM -0500, Ronald J. Kimball wrote​:

This is a bug report for perl from rjk@​linguist.dartmouth.edu,
generated with the help of perlbug 1.26 running under perl 5.00503.

-----------------------------------------------------------------
[Please enter your report here]

Math​::BigFloat​::fcmp() incorrectly determines that 0 is greater than any
positive non-integer. This occurs because in BigFloat's representation of
0 (+0E+0) has an exponent of 0, while its representation of a non-integer
such as 0.9 (+9E-1) has a negative exponent. fcmp() compares the exponents
without noting that one of the operands is equal to 0.

I note the following in Math​::BigFloat's documentation​:

BUGS

The current version of this module is a preliminary version of the
real thing that is currently (as of perl5.002) under development.

Is the "real thing" still under active development?

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