-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
bigint.php
118 lines (118 loc) · 2.57 KB
/
bigint.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
class BigInt
{
public static function cmp($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_cmp($left, $right);
return bccomp($left, $right);
}
public static function add($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_add($left, $right);
return bcadd($left, $right);
}
public static function sub($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_sub($left, $right);
return bcsub($left, $right);
}
public static function mul($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_mul($left, $right);
return bcmul($left, $right);
}
public static function div($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_div_q($left, $right);
return bcdiv($left, $right);
}
public static function mod($left, $right)
{
if (USE_EXT == 'GMP')
return gmp_mod($left, $right);
return bcmod($left, $right);
}
public static function pow($base, $exp)
{
if (USE_EXT == 'GMP')
return gmp_pow($base, $exp);
return bcpow($base, $exp);
}
public static function neg($val)
{
if (USE_EXT == 'GMP')
return gmp_neg($val);
if ($val[0] === '-')
return substr($val, 1);
return '-'.$val;
}
public static function bc_floor($val)
{
if (strpos($val, '.') === 0)
return $val;
$val = substr($val, 0, strpos($val, '.'));
if ($val[0] === '-')
$val = bcadd($val, -1);
return $val;
}
public static function div_qr($left, $right)
{
if (USE_EXT == 'GMP')
{
list($n, $d) = gmp_div_qr($left, $right);
return array($n, gmp_intval($d));
}
$q = self::bc_floor(bcdiv($left, $right, 4));
$r = bcsub($left, bcmul($q, $right));
return array($q, $r);
}
public static function bigintval($val)
{
if (USE_EXT == 'GMP')
return gmp_intval($val);
return intval($val);
}
public static function bin2big($binStr)
{
if (USE_EXT == 'GMP')
$v = gmp_init('0');
else
$v = '0';
$neg = false;
if (substr($binStr, 0, 4) == chr(0x80).chr(0).chr(0).chr(0))
{
$neg = true;
$binStr = substr($binStr, 4);
}
for ($i = 0; $i < strlen($binStr); $i++)
{
$v = self::add(self::mul($v, 256), ord($binStr[$i]));
}
if ($neg)
$v = self::neg($v);
return $v;
}
public static function big2bin($v)
{
$binStr = '';
$neg = false;
if (self::cmp($v, 0) < 0)
{
$neg = true;
$v = self::neg($v);
}
while (self::cmp($v, 0) > 0)
{
list($v, $r) = self::div_qr($v, 256);
$binStr = chr(self::bigintval($r)) . $binStr;
}
if ($neg)
$binStr = chr(0x80).str_repeat(chr(0), 3).$binStr;
return $binStr;
}
}