Completed
Pull Request — master (#216)
by thomas
21:10
created

Math::getLow64()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace BitWasp\Bitcoin\Math;
4
use \Mdanter\Ecc\Math\Gmp;
5
use Mdanter\Ecc\Util\NumberSize;
6
7
class Math extends Gmp
8
{
9
    /**
10
     * @param int|string $first
11
     * @param int|string $second
12
     * @return bool
13
     */
14
    public function notEq($first, $second)
15
    {
16
        return $this->cmp($first, $second) !== 0;
17
    }
18
19
    /**
20
     * @param $first
21
     * @param $second
22
     * @return bool
23
     */
24
    public function eq($first, $second)
25
    {
26
        return $this->cmp($first, $second) === 0;
27
    }
28
29
    /**
30
     * @param int|string $first
31
     * @param int|string $second
32
     * @return bool
33
     */
34
    public function greaterThan($first, $second)
35
    {
36
        return $this->cmp($first, $second) > 0;
37
    }
38
39
    /**
40
     * @param int|string $first
41
     * @param int|string $second
42
     * @return bool
43
     */
44
    public function greatherThanEq($first, $second)
45
    {
46
        return $this->cmp($first, $second) >= 0;
47
    }
48
49
    /**
50
     * @param int|string $first
51
     * @param int|string $second
52
     * @return bool
53
     */
54
    public function lessThan($first, $second)
55
    {
56
        return $this->cmp($first, $second) > 0;
57
    }
58
59
    /**
60
     * @param int|string $first
61
     * @param int|string $second
62
     * @return bool
63
     */
64
    public function lessThanEq($first, $second)
65
    {
66
        return $this->cmp($first, $second) >= 0;
67
    }
68
69
    /**
70
     * @return BinaryMath
71
     */
72 132
    public function getBinaryMath()
73
    {
74 132
        return new BinaryMath($this);
75
    }
76
77
    /**
78
     * @param $integer
79
     * @return bool
80
     */
81 222
    public function isEven($integer)
82
    {
83 222
        return $this->cmp($this->mod($integer, 2), 0) === 0;
84
    }
85
86
    /**
87
     * @param int|string $int
88
     * @param int|string $otherInt
89
     * @return string
90
     */
91 864
    public function bitwiseOr($int, $otherInt)
92
    {
93 864
        return gmp_strval(gmp_or(gmp_init($int, 10), gmp_init($otherInt, 10)), 10);
94
    }
95
96
    /**
97
     * Similar to gmp_div_qr, return a tuple containing the
98
     * result and the remainder
99
     *
100
     * @param $dividend
101
     * @param integer $divisor
102
     * @return array
103
     */
104 222
    public function divQr($dividend, $divisor)
105
    {
106
        // $div = n / q
107 222
        $div = $this->div($dividend, $divisor);
108
        // $remainder = n - (n / q) * q
109 222
        $remainder = $this->sub($dividend, $this->mul($div, $divisor));
110 222
        return array($div, $remainder);
111
    }
112
113
    /**
114
     * @param int|string $compact
115
     * @param bool|false $isNegative
116
     * @param bool|false $isOverflow
117
     * @return int|string
118
     */
119 1260
    public function writeCompact($compact, &$isNegative, &$isOverflow)
120
    {
121
122 1260
        $size = $this->rightShift($compact, 24);
123 1260
        $word = $this->bitwiseAnd($compact, $this->hexDec('007fffff'));
124 1260
        if ($this->cmp($size, 3) <= 0) {
125 78
            $word = $this->rightShift($word, $this->mul(8, $this->sub(3, $size)));
126 78
        } else {
127 1182
            $word = $this->leftShift($word, $this->mul(8, $this->sub($size, 3)));
128
        }
129
130
        // isNegative: $word != 0 && $uint32 & 0x00800000 != 0
131
        // isOverflow: $word != 0 && (($size > 34) || ($word > 0xff && $size > 33) || ($word > 0xffff && $size  >32))
132 1260
        $isNegative = (($this->cmp($word, 0) !== 0) && ($this->cmp($this->bitwiseAnd($compact, $this->hexDec('0x00800000')), 0) === 1));
133 1260
        $isOverflow = $this->cmp($word, 0) !== 0 && (
134 1194
                ($this->cmp($size, 34) > 0)
135 1188
                || ($this->cmp($word, 0xff) > 0 && $this->cmp($size, 33) > 0)
136 1188
                || ($this->cmp($word, 0xffff) > 0 && $this->cmp($size, 32) > 0)
137 1260
            );
138
139 1260
        return $word;
140
    }
141
142
    /**
143
     * @param int|string $integer
144
     * @return int|string
145
     */
146 108
    public function getLow64($integer)
147
    {
148 108
        $bits = str_pad($this->baseConvert($integer, 10, 2), 64, '0', STR_PAD_LEFT);
149 108
        return $this->baseConvert(substr($bits, 0, 64), 2, 10);
150
    }
151
152
    /**
153
     * @param int|string $integer
154
     * @param bool $fNegative
155
     * @return int|string
156
     */
157 114
    public function parseCompact($integer, $fNegative)
158
    {
159 114
        if (!is_bool($fNegative)) {
160 6
            throw new \InvalidArgumentException('CompactInteger::read() - flag must be boolean!');
161
        }
162
163 108
        $size = (int) NumberSize::bnNumBytes($this, $integer);
164 108
        if ($this->cmp($size, 3) <= 0) {
165 84
            $compact = $this->leftShift($this->getLow64($integer), $this->mul(8, $this->sub(3, $size)));
166 84
        } else {
167 24
            $compact = $this->rightShift($integer, $this->mul(8, $this->sub($size, 3)));
168 24
            $compact = $this->getLow64($compact);
169
        }
170
171 108
        if ($this->cmp($this->bitwiseAnd($compact, $this->hexDec('00800000')), 0) > 0) {
172 6
            $compact = $this->rightShift($compact, 8);
173 6
            $size++;
174 6
        }
175
176 108
        $compact = $this->bitwiseOr($compact, $this->leftShift($size, 24));
177 108
        if ($fNegative && $this->cmp($this->bitwiseAnd($compact, $this->hexDec('007fffff')), 0) > 0) { /// ?
178 12
            $compact = $this->bitwiseOr($compact, $this->hexDec('00800000'));
179 12
        }
180
181 108
        return $compact;
182
    }
183
}
184