Use a macro for abs() to avoid the possible truncation to an int;
Jarkko Hietaniemi [Mon, 3 Mar 2003 05:33:21 +0000 (05:33 +0000)]
also make an explicit (double)cast for the arguments to fabs().

p4raw-id: //depot/perl@18813

perl.h
pp.c
sv.c
util.c

diff --git a/perl.h b/perl.h
index a2f8c43..0253a43 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -4240,6 +4240,10 @@ extern void moncontrol(int);
 #   define PERL_BLOCKSIG_UNBLOCK(set)  NOOP
 #endif
 
+/* Use instead of abs() since abs() forces its argument to be an int,
+ * but also beware since evaluates its argument thrice. */
+#define PERL_ABS(x) ((x) < 0 ? -(x) : (x))
+
 /* and finally... */
 #define PERL_PATCHLEVEL_H_IMPLICIT
 #include "patchlevel.h"
diff --git a/pp.c b/pp.c
index 0a15c74..bb3ac68 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -1236,7 +1236,7 @@ PP(pp_divide)
                     }
                     RETURN;
                 } /* tried integer divide but it was not an integer result */
-            } /* else (abs(result) < 1.0) or (both UVs in range for NV) */
+            } /* else (PERL_ABS(result) < 1.0) or (both UVs in range for NV) */
         } /* left wasn't SvIOK */
     } /* right wasn't SvIOK */
 #endif /* PERL_TRY_UV_DIVIDE */
@@ -2483,9 +2483,7 @@ PP(pp_i_modulo_1)
          dPOPTOPiirl;
          if (!right)
               DIE(aTHX_ "Illegal modulus zero");
-         if (right < 0)
-              right = -right;
-         SETi( left % right );
+         SETi( left % PERL_ABS(right) );
          RETURN;
      }
 #endif
@@ -2522,8 +2520,7 @@ PP(pp_i_modulo)
                         PL_ppaddr[OP_I_MODULO] =
                             &Perl_pp_i_modulo_1;
                    /* Make certain we work right this time, too. */
-                   if (right < 0)
-                        right = -right;
+                   right = PERL_ABS(right);
               }
          }
 #endif
diff --git a/sv.c b/sv.c
index 777468f..350071e 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2273,7 +2273,7 @@ Perl_sv_2iv(pTHX_ register SV *sv)
                        this NV is in the preserved range, therefore: */
                     if (!(U_V(SvNVX(sv) > 0 ? SvNVX(sv) : -SvNVX(sv))
                           < (UV)IV_MAX)) {
-                        Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs(SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
+                        Perl_croak(aTHX_ "sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
                     }
                 } else {
                     /* IN_UV NOT_INT
@@ -2560,7 +2560,7 @@ Perl_sv_2uv(pTHX_ register SV *sv)
                        this NV is in the preserved range, therefore: */
                     if (!(U_V(SvNVX(sv) > 0 ? SvNVX(sv) : -SvNVX(sv))
                           < (UV)IV_MAX)) {
-                        Perl_croak(aTHX_ "sv_2uv assumed (U_V(fabs(SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
+                        Perl_croak(aTHX_ "sv_2uv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%"NVgf" U_V is 0x%"UVxf", IV_MAX is 0x%"UVxf"\n", SvNVX(sv), U_V(SvNVX(sv)), (UV)IV_MAX);
                     }
                 } else
                     sv_2iuv_non_preserve (sv, numtype);
diff --git a/util.c b/util.c
index bd6821a..b13a347 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3778,7 +3778,7 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
                        orev = rev;
                        rev += (*s - '0') * mult;
                        mult /= 10;
-                       if ( abs(orev) > abs(rev) )
+                       if ( PERL_ABS(orev) > PERL_ABS(rev) )
                            Perl_croak(aTHX_ "Integer overflow in version");
                        s++;
                    }
@@ -3788,7 +3788,7 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
                        orev = rev;
                        rev += (*end - '0') * mult;
                        mult *= 10;
-                       if ( abs(orev) > abs(rev) )
+                       if ( PERL_ABS(orev) > PERL_ABS(rev) )
                            Perl_croak(aTHX_ "Integer overflow in version");
                    }
                } 
@@ -3907,11 +3907,11 @@ Perl_vnumify(pTHX_ SV *vs)
        return sv;
     }
     digit = SvIVX(*av_fetch((AV *)vs, 0, 0));
-    Perl_sv_setpvf(aTHX_ sv,"%d.",abs(digit));
+    Perl_sv_setpvf(aTHX_ sv,"%d.", PERL_ABS(digit));
     for ( i = 1 ; i <= len ; i++ )
     {
        digit = SvIVX(*av_fetch((AV *)vs, i, 0));
-       Perl_sv_catpvf(aTHX_ sv,"%03d",abs(digit));
+       Perl_sv_catpvf(aTHX_ sv,"%03d", PERL_ABS(digit));
     }
     if ( len == 0 )
         Perl_sv_catpv(aTHX_ sv,"000");
@@ -3989,8 +3989,8 @@ Perl_vcmp(pTHX_ SV *lsv, SV *rsv)
        I32 right = SvIV(*av_fetch((AV *)rsv,i,0));
        bool lbeta = left  < 0 ? 1 : 0;
        bool rbeta = right < 0 ? 1 : 0;
-       left  = abs(left);
-       right = abs(right);
+       left  = PERL_ABS(left);
+       right = PERL_ABS(right);
        if ( left < right || (left == right && lbeta && !rbeta) )
            retval = -1;
        if ( left > right || (left == right && rbeta && !lbeta) )