~ubuntu-branches/ubuntu/vivid/nqp/vivid-proposed

« back to all changes in this revision

Viewing changes to t/nqp/60-bigint.t

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-11-01 12:09:18 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20131101120918-kx51sl0sxl3exsxi
Tags: 2013.10-1
* New upstream release
* Bump versioned (Build-)Depends on parrot
* Update patches
* Install new README.pod
* Fix vcs-field-not-canonical
* Do not install rubyish examples
* Do not Depends on parrot-devel anymore
* Add 07_disable-serialization-tests.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
use nqpmo;
3
3
 
4
4
plan(0);
 
5
nqp::exit(0);
 
6
 
 
7
plan(47);
 
8
 
 
9
my $knowhow := nqp::knowhow();
 
10
my $bi_type := $knowhow.new_type(:name('TestBigInt'), :repr('P6bigint'));
 
11
$bi_type.HOW.compose($bi_type);
 
12
sub str($x) { nqp::tostr_I($x) };
 
13
sub iseq($x, $y) { nqp::iseq_I($x, nqp::box_i($y, $bi_type)) }
 
14
sub box($x) { nqp::box_i($x, $bi_type) }
 
15
 
 
16
my $one := box(1);
 
17
 
 
18
my $b := nqp::fromstr_I('-123', $one);
 
19
my $c := box(-123);
 
20
 
 
21
ok(str($b) eq '-123', 'can round-trip negative number (string)');
 
22
ok(str($c) eq '-123', 'can round-trip negative number (string) by boxing');
 
23
ok(nqp::unbox_i($b) == -123, 'can round-trip negative number by unboxing');
 
24
ok(!nqp::iseq_I($one, $b), 'nqp::iseq_I can return false');
 
25
ok(nqp::iseq_I($one, $one), 'nqp::iseq_I can return true');
 
26
ok(iseq(nqp::mul_I($b, $b, $b), 15129,), 'multiplication');
 
27
ok(iseq(nqp::add_I($b, $b, $b),  -246,), 'addition');
 
28
ok(nqp::iseq_I(nqp::sub_I($b, $b, $b), nqp::box_i(0, $bi_type)), 'subtraction');
 
29
ok(nqp::iseq_I(nqp::div_I($b, $b, $b), $one), 'division');
 
30
 
 
31
ok(iseq(nqp::bitshiftl_I($one, 3, $one), 8), 'bitshift left');
 
32
ok(iseq($one, 1), 'original not modified by bitshift left');
 
33
ok(iseq(nqp::bitshiftr_I(box(16), 4, $one), 1), 'bitshift right');
 
34
 
 
35
ok(iseq(nqp::bitand_I(box(0xdead), box(0xbeef), $one), 0x9ead), 'bit and');
 
36
ok(iseq(nqp::bitor_I( box(0xdead), box(0xbeef), $one), 0xfeef), 'bit or');
 
37
ok(iseq(nqp::bitxor_I(box(0xdead), box(0xbeef), $one), 0x6042), 'bit xor');
 
38
 
 
39
ok(iseq(nqp::bitneg_I(box(-123), $one), 122), 'bit negation');
 
40
 
 
41
ok(iseq(nqp::bitand_I(nqp::fromstr_I('-1073741825', $one), $one, $one), 1),
 
42
    'Bit ops (RT 109740)');
 
43
 
 
44
# Now we'll create a type that boxes a P6bigint.
 
45
my $bi_boxer := NQPClassHOW.new_type(:name('TestPerl6Int'), :repr('P6opaque'));
 
46
$bi_boxer.HOW.add_attribute($bi_boxer, NQPAttribute.new(
 
47
    :name('$!value'), :type($bi_type), :box_target(1)
 
48
));
 
49
$bi_boxer.HOW.add_parent($bi_boxer, NQPMu);
 
50
$bi_boxer.HOW.compose($bi_boxer);
 
51
 
 
52
# Try some basic operations with it.
 
53
my $box_val_1 := nqp::box_i(4, $bi_boxer);
 
54
ok(iseq($box_val_1, 4), 'can box to a complex type with a P6bigint target');
 
55
my $box_val_2 := nqp::fromstr_I('38', $bi_boxer);
 
56
ok(iseq($box_val_2, 38), 'can get a bigint from a string with boxing type');
 
57
ok(iseq(nqp::add_I($box_val_1, $box_val_2, $bi_boxer), 42), 'addition works on boxing type');
 
58
 
 
59
 
 
60
# Note that the last argument to pow_I should be capable of boxing a num,
 
61
# so $bi_type is wrong here. But so far we only test the integer case,
 
62
# so we can get away with it.
 
63
my $big := nqp::pow_I($c, box(42), $bi_type, $bi_type);
 
64
ok(str($big) eq '5970554685064519004265641008828923248442340700473500698131071806779372733915289638628729', 'pow (int, positive)');
 
65
ok(iseq(nqp::pow_I(box(0), $big, $bi_type, $bi_type), 0), 'pow 0 ** large_number');
 
66
ok(iseq(nqp::pow_I($one, $big, $bi_type, $bi_type), 1), 'pow 1 ** large_number');
 
67
 
 
68
# test conversion to float
 
69
# try it with 2 ** 100, because that's big enough not to fit into a single
 
70
# int, but can be represented exactly in a double
 
71
$big := nqp::pow_I(box(2), box(100), $bi_type, $bi_type);
 
72
ok(nqp::iseq_n(nqp::tonum_I($big), nqp::pow_n(2, 100)), '2**100 to float');
 
73
$big := nqp::pow_I(box(-2), box(101), $bi_type, $bi_type);
 
74
ok(nqp::iseq_n(nqp::tonum_I($big), nqp::pow_n(-2, 101)), '(-2)**101 to float');
 
75
# the mantissa can hold much information accurately, so test that too
 
76
my $factor := 123456789;
 
77
$big := nqp::mul_I($big, box($factor), $bi_type);
 
78
ok(nqp::iseq_n(nqp::tonum_I($big), nqp::mul_n($factor, nqp::pow_n(-2, 101))), "$factor * (-2)**101 to float");
 
79
 
 
80
$big := 1e16;
 
81
my $converted := nqp::tonum_I(nqp::fromstr_I('10000000000000000', $bi_type));
 
82
ok(nqp::abs_n($big - $converted) / $big < 1e-4, 'bigint -> float, 1e16');
 
83
 
 
84
my $float := 123456789e240;
 
85
ok(nqp::iseq_n($float, nqp::tonum_I(nqp::fromnum_I($float, $bi_type))),
 
86
    'to_num and from_num round-trip');
 
87
my $small_float := 1e3;
 
88
ok(nqp::iseq_n($small_float, nqp::tonum_I(nqp::fromnum_I($small_float, $bi_type))),
 
89
    'to_num and from_num round-trip on small floats');
 
90
my $medium_float := 1e14;
 
91
ok(nqp::iseq_n($medium_float, nqp::tonum_I(nqp::fromnum_I($medium_float, $bi_type))),
 
92
    'to_num and from_num round-trip on medium sized floats');
 
93
$float := -$float;
 
94
ok(nqp::iseq_n($float, nqp::tonum_I(nqp::fromnum_I($float, $bi_type))),
 
95
    'to_num and from_num round-trip (negative number)');
 
96
 
 
97
ok(nqp::base_I(box(-1234), 10) eq '-1234', 'base_I with base 10');
 
98
ok(nqp::base_I(box(-1234), 16) eq '-4D2',  'base_I with base 16');
 
99
 
 
100
ok(str(nqp::expmod_I(
 
101
    nqp::fromstr_I('2988348162058574136915891421498819466320163312926952423791023078876139', $bi_type),
 
102
    nqp::fromstr_I('2351399303373464486466122544523690094744975233415544072992656881240319', $bi_type),
 
103
    nqp::fromstr_I('10000000000000000000000000000000000000000', $bi_type),
 
104
    $bi_type,
 
105
)) eq '1527229998585248450016808958343740453059', 'nqp::expmod_I');
 
106
 
 
107
ok(nqp::div_In(box(1234500), box(100)) == 12345, 'div_In santiy');
 
108
my $n := nqp::div_In(
 
109
    nqp::pow_I(box(203), box(200), $bi_type, $bi_type),
 
110
    nqp::pow_I(box(200), box(200), $bi_type, $bi_type),
 
111
);
 
112
ok(nqp::abs_n($n - 19.6430286394751) < 1e-10, 'div_In with big numbers');
 
113
 
 
114
my $maxRand := nqp::fromstr_I('10000000000000000000000000000000000000000', $bi_type);
 
115
my $rand := nqp::rand_I($maxRand, $bi_type); 
 
116
ok(nqp::isle_I(box(0), $rand) && nqp::islt_I($rand, $maxRand), 'nqp::rand_I');
 
117
 
 
118
ok(nqp::isprime_I(box(-4), 1) == 0, 'is -4 prime');
 
119
ok(nqp::isprime_I(box(0), 1) == 0, 'is 0 prime');
 
120
ok(nqp::isprime_I(box(1), 1) == 0, 'is 1 prime');
 
121
ok(nqp::isprime_I(box(2), 1) == 1, 'is 2 prime');
 
122
ok(nqp::isprime_I(box(4), 1) == 0, 'is 4 prime');
 
123
ok(nqp::isprime_I(box(17), 1) == 1, 'is 17 prime');
 
124
 
 
125
ok(nqp::iseq_I(nqp::gcd_I(box(18), box(12), $bi_type), box(6)), 'nqp::gcd_I');
 
126
ok(nqp::iseq_I(nqp::lcm_I(box(18), box(12), $bi_type), box(36)), 'nqp::lcm_I');
 
127
 
 
128
ok(nqp::bool_I(box(42)), 'bool_I(42)');
 
129
ok(!nqp::bool_I(box(0)), 'bool_I(0)');