6 t/pmc/bignum.t - Test the non-implemented BigNum PMC.
10 Does nothing yet, as there is no BigNum PMC yet.
12 The idea is to run the test cases parsed out of *.decTest, available
13 from: http://www2.hursley.ibm.com/decimal/dectest.html
17 This was started by Alex Gogh, who went to work in Antarctica, http://the.earth.li/~alex/halley/.
18 The script was supposed to test bignum.c, which should become the basis for a
27 F<docs/docs/pdds/draft/pdd14_bignum.pod>,
28 L<https://rt.perl.org/rt3/Ticket/Display.html?id=36330>
35 use Test::More skip_all => 'No BigNum support yet.';
37 my ( $test, $one, $two, $result, $prec, $round, $maxexp, $skip, $op, @conds, $line, $arrow );
39 my ( $testsrun, $testspass, $testsfail, $extended ) = ( 0, 0, 0, 0 );
44 s/\s*--.*$//; # and hope it's not quoted
46 /^precision:\s+(\d+)/ && do {
50 /^rounding:\s*(\w+)/ && do {
54 /^extended:\s*(\d+)/ && do {
59 /^maxexponent:\s*(\d+)/i && do {
60 $expskip = 1 if ( $1 > $maxexp );
61 if ( $1 <= $maxexp ) {
67 ( $test, $op, $one, $two, $arrow, $result, @conds ) = split( /\s+/, $_ );
70 if ( $one eq '#' || $two eq '#' ) {
71 print "$test ok \# skip, null test\n";
75 if ( $round !~ /^(half_up|half_even|down|floor|ceiling)$/ ) {
76 print "$test ok \# skip, $round not available\n";
80 if ( $op =~ /^(power|rescale)$/ ) {
81 print "$test ok \# skip, $op not implemented\n";
85 if ( $two eq '->' ) { # unary op
86 unshift( @conds, $result ) if defined $result;
87 ( $two, $result, @conds ) = ( '0', $arrow, @conds );
90 if ( !defined($result) ) {
96 print "$test ok \# skip\n";
100 for ( $one, $two, $result ) {
105 my ($output) = run_single_test( $one $two $op $precision $round $extended );
107 my @out = split( /\s+/, $output );
108 if ( $result eq $out[0] || ( $result eq '?' ) ) {
113 print "$test not ok\n";
114 print " $one $op $two\n (p:$precision r:$round)\n";
115 print " => `", join( "'`", @out ), "'\n";
116 print " ex `$result', ", ( @conds ? join( " ", @conds ) : '-' ), "\n";
121 my ( %conds, %outs );
125 # need to map conditions, as signals and conditions don't quite mesh
127 Division_impossible => 'Invalid_operation',
128 Division_undefined => 'Invalid_operation'
136 $conds{$_} = 1 foreach @conds;
137 $outs{$_} = 1 foreach @out[ 1 .. ( @out - 1 ) ];
139 foreach ( keys %conds ) {
140 $tpass = 0 unless $outs{$_};
142 foreach ( keys %outs ) {
143 $tpass = 0 unless $conds{$_};
147 elsif ( @out == 1 ) {
156 print "$test not ok\n";
157 print " $one $op $two\n (p:$precision r:$round)\n";
158 print " => `", join( "'`", @out ), "'\n";
159 print " ex `$result', ", ( @conds ? join( " ", @conds ) : '-' ), "\n";
165 # XXX The following used to be bignum_test.pl.
166 # Maybe it should be factored out to Parrot::Test::BigNum.
168 # This allows a single bignum test to be run directly through the C
169 # library. Usage available by getting the args wrong.
172 use Inline C => Config => CCFLAGS => '-I.';
173 use Inline C => <<'END_OF_C_SECTION';
176 int runtest (char* lef, char *rih, int oper, int prec, int round, int extended) {
177 BIGNUM *one, *two, *result;
180 char *traps[7] = {"Lost_digits","Division_by_zero","Inexact",
181 "Invalid_operation","Overflow","Rounded","Underflow"};
183 context.elimit = 999999999;
184 context.precision = prec;
185 context.extended = extended;
189 case 1 : context.rounding = ROUND_HALF_UP;
191 case 2 : context.rounding = ROUND_DOWN;
193 case 3 : context.rounding = ROUND_HALF_EVEN;
195 case 4 : context.rounding = ROUND_CEILING;
197 case 5 : context.rounding = ROUND_FLOOR;
199 default : printf("Unknown rounding %i\n", round);
203 one = BN_from_string(lef, &context);
204 two = BN_from_string(rih, &context);
209 case 1 : BN_add(result, one, two, &context);
211 case 2 : BN_subtract(result, one, two, &context);
213 case 3 : BN_plus(result, one, &context);
215 case 4 : BN_minus(result, one, &context);
217 case 5 : BN_compare(result, one, two, &context);
219 case 6 : BN_multiply(result, one, two, &context);
221 case 7 : BN_divide(result, one, two, &context);
223 case 8 : BN_divide_integer(result, one, two, &context);
225 case 9 : BN_remainder(result, one, two, &context);
227 case 10: BN_rescale(result, one, two, &context);
229 case 11: BN_power(result, one, two, &context);
232 default : printf("No operation of type %i\n", oper);
236 BN_to_scientific_string(result, &output);
237 printf("%s", output);
241 if ((1 << i) & context.flags) printf(" %s", traps[i]);
270 sub run_single_test {
273 bignum_test.pl -- run test through bignum.c
274 bignum_test.pl one two operation precision rounding extended
278 for ( $_[0], $_[1] ) {
286 runtest( $_[0], $_[1], $ops{ $ARGV[2] }, $_[3], $round{ $_[4] }, $_[5] );
291 # cperl-indent-level: 4
294 # vim: expandtab shiftwidth=4: