# New Ticket Created by Tony Payne
# Please include the string: [perl #825]
# in the subject line of all future correspondence about this issue.
# <URL: http://bugs6.perl.org/rt2/Ticket/Display.html?id=825 >
Conversion from a signed (int,float) to an unsigned int was causing
underflow. Therefore, fact(-1) becomes fact(UINT_MAX), which is
absurdly large :-). With this patch, it returns 0. Tests are also
included.
++t
-- attachment 1 ------------------------------------------------------
url: http://bugs6.perl.org/rt2/attach/3880/3590/523641/fact.diff
Index: math.ops
===================================================================
RCS file: /cvs/public/parrot/math.ops,v
retrieving revision 1.1
diff -u -r1.1 math.ops
--- math.ops 17 Jun 2002 18:06:11 -0000 1.1
+++ math.ops 16 Jul 2002 22:03:46 -0000
@@ -122,8 +122,9 @@
=cut
inline op fact(out INT, in INT) {
-
-UINTVAL i = $2;
+/* Coercing a negative to a UINT can get pretty ugly
+ * in this situation. */
+INTVAL i = $2;
UINTVAL q = 1;
while(i>0) {
q = q*i;
@@ -134,8 +135,9 @@
}
inline op fact(out NUM, in INT) {
-
-UINTVAL i = $2;
+/* Coercing a negative to a UINT can get pretty ugly
+ * in this situation. */
+INTVAL i = $2;
UINTVAL q = 1;
while(i>0) {
q = q*i;
Index: t/op/integer.t
===================================================================
RCS file: /cvs/public/parrot/t/op/integer.t,v
retrieving revision 1.25
diff -u -r1.25 integer.t
--- t/op/integer.t 28 Jun 2002 18:50:40 -0000 1.25
+++ t/op/integer.t 16 Jul 2002 22:03:46 -0000
@@ -1,6 +1,6 @@
#! perl -w
-use Parrot::Test tests => 33;
+use Parrot::Test tests => 35;
output_is(<<CODE, <<OUTPUT, "set_i_ic");
# XXX: Need a test for writing outside the set of available
@@ -1044,6 +1044,52 @@
end
CODE
12
+OUTPUT
+
+output_is(<<CODE, <<OUTPUT, "fact_i_i");
+ set I0, 3
+ set I1, 11
+ set I2, 0
+ set I3, -563
+ fact I5, I0
+ print I5
+ print "\\n"
+ fact I6, I1
+ print I6
+ print "\\n"
+ fact I7, I2
+ print I7
+ print "\\n"
+ fact I8, I3
+ print I8
+ print "\\n"
+ end
+CODE
+6
+39916800
+1
+1
+OUTPUT
+
+output_is(<<CODE, <<OUTPUT, "fact_i_ic");
+ fact I5, 3
+ print I5
+ print "\\n"
+ fact I6, 11
+ print I6
+ print "\\n"
+ fact I7, 0
+ print I7
+ print "\\n"
+ fact I8, -563
+ print I8
+ print "\\n"
+ end
+CODE
+6
+39916800
+1
+1
OUTPUT
1;
Index: t/op/number.t
===================================================================
RCS file: /cvs/public/parrot/t/op/number.t,v
retrieving revision 1.19
diff -u -r1.19 number.t
--- t/op/number.t 28 Jun 2002 18:50:40 -0000 1.19
+++ t/op/number.t 16 Jul 2002 22:03:46 -0000
@@ -1,6 +1,6 @@
#! perl -w
-use Parrot::Test tests => 30;
+use Parrot::Test tests => 32;
use Test::More;
output_is(<<CODE, <<OUTPUT, "set_n_nc");
@@ -900,6 +900,52 @@
end
CODE
12.000000
+OUTPUT
+
+output_is(<<CODE, <<OUTPUT, "fact_n_i");
+ set I0, 3
+ set I1, 11
+ set I2, 0
+ set I3, -563
+ fact N5, I0
+ print N5
+ print "\\n"
+ fact N6, I1
+ print N6
+ print "\\n"
+ fact N7, I2
+ print N7
+ print "\\n"
+ fact N8, I3
+ print N8
+ print "\\n"
+ end
+CODE
+6.000000
+39916800.000000
+1.000000
+1.000000
+OUTPUT
+
+output_is(<<CODE, <<OUTPUT, "fact_n_ic");
+ fact N5, 3
+ print N5
+ print "\\n"
+ fact N6, 11
+ print N6
+ print "\\n"
+ fact N7, 0
+ print N7
+ print "\\n"
+ fact N8, -563
+ print N8
+ print "\\n"
+ end
+CODE
+6.000000
+39916800.000000
+1.000000
+1.000000
OUTPUT
1;