| 1 |
module etc.bigint.bigint_int; |
|---|
| 2 |
import etc.bigint.exception; |
|---|
| 3 |
import etc.bigint.multiply; |
|---|
| 4 |
import etc.bigint.radix; |
|---|
| 5 |
private import std.c.stdlib; |
|---|
| 6 |
private import std.math; |
|---|
| 7 |
private import std.string; |
|---|
| 8 |
|
|---|
| 9 |
/* |
|---|
| 10 |
|
|---|
| 11 |
Copyright (c) 2004, Arcane Jill |
|---|
| 12 |
|
|---|
| 13 |
All rights reserved. Intellectual Property Me Arse! |
|---|
| 14 |
|
|---|
| 15 |
Redistribution and use in source and binary forms, with or without modification, are permitted |
|---|
| 16 |
provided that the following conditions are met: |
|---|
| 17 |
|
|---|
| 18 |
* Redistributions of source code must retain the above copyright notice, the phrase |
|---|
| 19 |
"Intellectual Property Me Arse!", this list of conditions, and the following disclaimer. |
|---|
| 20 |
* Redistributions in binary form must reproduce the above copyright notice, the phrase |
|---|
| 21 |
"Intellectual Property Me Arse!", this list of conditions and the following disclaimer |
|---|
| 22 |
in the documentation and/or other materials provided with the distribution. |
|---|
| 23 |
* The name Arcane Jill may not be used to endorse or promote products derived from this |
|---|
| 24 |
software without specific prior written permission. |
|---|
| 25 |
|
|---|
| 26 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS |
|---|
| 27 |
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
|---|
| 28 |
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, |
|---|
| 29 |
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|---|
| 30 |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|---|
| 31 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED, AND ON ANY |
|---|
| 32 |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
|---|
| 33 |
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
|---|
| 34 |
OF SUCH DAMAGE. |
|---|
| 35 |
|
|---|
| 36 |
*/ |
|---|
| 37 |
|
|---|
| 38 |
class Int |
|---|
| 39 |
{ |
|---|
| 40 |
unittest |
|---|
| 41 |
{ |
|---|
| 42 |
Int a,b,c,d; |
|---|
| 43 |
|
|---|
| 44 |
//------------------------------------------ |
|---|
| 45 |
// Test comparisons |
|---|
| 46 |
a = new Int(0xAAAAAAAA); |
|---|
| 47 |
b = new Int(0xAAAAAAAA); |
|---|
| 48 |
c = new Int(0xCCCCCCCC); |
|---|
| 49 |
d = new Int("0x00000001AAAAAAAA"); |
|---|
| 50 |
assert(a == b); |
|---|
| 51 |
assert(a < c); |
|---|
| 52 |
assert(c > a); |
|---|
| 53 |
assert(a < d); |
|---|
| 54 |
assert(d > a); |
|---|
| 55 |
d = new Int(-1); |
|---|
| 56 |
assert(d < a); |
|---|
| 57 |
|
|---|
| 58 |
//------------------------------------------ |
|---|
| 59 |
// Test add and subtract |
|---|
| 60 |
a = b + c; |
|---|
| 61 |
d = new Int("0x0000000177777776"); |
|---|
| 62 |
assert(a == d); |
|---|
| 63 |
assert(a - b == c); |
|---|
| 64 |
c = -d; |
|---|
| 65 |
assert(c+d == 0); |
|---|
| 66 |
|
|---|
| 67 |
//------------------------------------------ |
|---|
| 68 |
// Test multiply and divide for small values |
|---|
| 69 |
a = new Int(0x11111111); |
|---|
| 70 |
a = -a; |
|---|
| 71 |
b = a * a; |
|---|
| 72 |
c = new Int("0x0123456787654321"); |
|---|
| 73 |
assert(b == c); |
|---|
| 74 |
b = b / a; |
|---|
| 75 |
assert(b == a); |
|---|
| 76 |
a = new Int(22); |
|---|
| 77 |
assert(a / 7 == 3); |
|---|
| 78 |
assert(a % 7 == 1); |
|---|
| 79 |
assert(a / -7 == -3); |
|---|
| 80 |
assert(a % -7 == 1); |
|---|
| 81 |
a = -a; |
|---|
| 82 |
assert(a / 7 == -3); |
|---|
| 83 |
assert(a % 7 == -1); |
|---|
| 84 |
assert(a / -7 == 3); |
|---|
| 85 |
assert(a % -7 == -1); |
|---|
| 86 |
a = -a; |
|---|
| 87 |
b = new Int(7); |
|---|
| 88 |
c = -b; |
|---|
| 89 |
assert(divMod(a, b, d, Round.TOWARD_MINUS_INFINITY) == 3); |
|---|
| 90 |
assert(d == 1); |
|---|
| 91 |
assert(divMod(a, c, d, Round.TOWARD_MINUS_INFINITY) == -4); |
|---|
| 92 |
assert(d == -6); |
|---|
| 93 |
a = -a; |
|---|
| 94 |
assert(divMod(a, b, d, Round.TOWARD_MINUS_INFINITY) == -4); |
|---|
| 95 |
assert(d == 6); |
|---|
| 96 |
assert(divMod(a, c, d, Round.TOWARD_MINUS_INFINITY) == 3); |
|---|
| 97 |
assert(d == -1); |
|---|
| 98 |
|
|---|
| 99 |
//------------------------------------------ |
|---|
| 100 |
// Test multiply and divide for large values |
|---|
| 101 |
a = new Int("0x0111111111111111"); |
|---|
| 102 |
b = a * a; |
|---|
| 103 |
c = new Int("0x000123456789ABCDEFEDCBA987654321"); |
|---|
| 104 |
assert(b == c); |
|---|
| 105 |
b = b / a; |
|---|
| 106 |
assert(b == a); |
|---|
| 107 |
|
|---|
| 108 |
//------------------------------------------ |
|---|
| 109 |
// Test binary operations |
|---|
| 110 |
a = new Int("0x1234567812345678"); |
|---|
| 111 |
uint n = a & 0xFFFFu; |
|---|
| 112 |
assert(n == 0x5678); |
|---|
| 113 |
b = a & new Int(0xFF00FF); |
|---|
| 114 |
assert(b == new Int(0x340078)); |
|---|
| 115 |
c = a | 0xFFFF; |
|---|
| 116 |
assert(c == new Int("0x123456781234FFFF")); |
|---|
| 117 |
d = a ^ 0xFFFFFFFF; |
|---|
| 118 |
assert (d == new Int("0x12345678EDCBA987")); |
|---|
| 119 |
c = d & -1; |
|---|
| 120 |
assert(c == d); |
|---|
| 121 |
c = ~d; |
|---|
| 122 |
assert((c ^ (-1)) == d); |
|---|
| 123 |
|
|---|
| 124 |
//------------------------------------------ |
|---|
| 125 |
// Test shift left and shift right |
|---|
| 126 |
a = new Int(0x12345678); |
|---|
| 127 |
b = a << 40; |
|---|
| 128 |
c = new Int("0x000000123456780000000000"); |
|---|
| 129 |
assert(b == c); |
|---|
| 130 |
d = c << -40; |
|---|
| 131 |
assert(d == a); |
|---|
| 132 |
d = c >>> 40; |
|---|
| 133 |
assert(d == a); |
|---|
| 134 |
c = -c; |
|---|
| 135 |
a = -a; |
|---|
| 136 |
d = c << -40; |
|---|
| 137 |
assert(d == a); |
|---|
| 138 |
try |
|---|
| 139 |
{ |
|---|
| 140 |
d = c >>> 40; |
|---|
| 141 |
} |
|---|
| 142 |
catch (IntException) |
|---|
| 143 |
{ |
|---|
| 144 |
b = ZERO; |
|---|
| 145 |
} |
|---|
| 146 |
assert(b == 0); |
|---|
| 147 |
d = c >>> 0; |
|---|
| 148 |
assert(c == d); |
|---|
| 149 |
|
|---|
| 150 |
//------------------------------------------ |
|---|
| 151 |
// Test the array-like functions |
|---|
| 152 |
|
|---|
| 153 |
a = new Int("0xFEDCBA98_76543210_00000000_00000000_FEDCBA98_76543210"); |
|---|
| 154 |
assert(a[1] == 0xFEDCBA98); |
|---|
| 155 |
assert(a[3000] == 0); |
|---|
| 156 |
assert(a[0..2] == a[4..6]); |
|---|
| 157 |
assert(a[100..115] == a[200..215]); |
|---|
| 158 |
assert(a[0..4] == a[4..8]); |
|---|
| 159 |
|
|---|
| 160 |
//------------------------------------------ |
|---|
| 161 |
// Test formatting |
|---|
| 162 |
|
|---|
| 163 |
a = new Int(123); |
|---|
| 164 |
assert(a.format(10, 0, 0, false, SignMode.NORMAL) == "123"); |
|---|
| 165 |
assert(a.format(10, 0, 0, false, SignMode.MINUS_SPACE_PLUS) == "+123"); |
|---|
| 166 |
assert(a.format(10, 0, 0, true, SignMode.NORMAL) == "123"); |
|---|
| 167 |
assert(a.format(10, 0, 2, false, SignMode.NORMAL) == "1_23"); |
|---|
| 168 |
assert(a.format(10, 5, 0, false, SignMode.NORMAL) == " 123"); |
|---|
| 169 |
assert(a.format(10, 5, 0, false, SignMode.MINUS_SPACE_PLUS) == " +123"); |
|---|
| 170 |
assert(a.format(10, 5, 0, true, SignMode.NORMAL) == "00123"); |
|---|
| 171 |
assert(a.format(10, 5, 0, true, SignMode.MINUS_SPACE_PLUS) == "+0123"); |
|---|
| 172 |
assert(a.format(10, 5, 2, false, SignMode.NORMAL) == " 1_23"); |
|---|
| 173 |
a = -a; |
|---|
| 174 |
assert(a.format(10, 5, 0, false, SignMode.NORMAL) == " -123"); |
|---|
| 175 |
assert(a.format(10, 5, 0, true, SignMode.NORMAL) == "-0123"); |
|---|
| 176 |
assert(a.format(10, 5, 2, false, SignMode.NORMAL) == "-1_23"); |
|---|
| 177 |
|
|---|
| 178 |
a = new Int("123456"); |
|---|
| 179 |
assert(a.toString() == "123456"); |
|---|
| 180 |
a = new Int("0x123456"); |
|---|
| 181 |
assert(a.toHexString() == "123456"); |
|---|
| 182 |
|
|---|
| 183 |
a = new Int("0"); |
|---|
| 184 |
assert (a.toString == "0"); |
|---|
| 185 |
assert (ZERO.toString == "0"); |
|---|
| 186 |
assert (a == ZERO); |
|---|
| 187 |
assert (a == new Int(0)); |
|---|
| 188 |
} |
|---|
| 189 |
|
|---|
| 190 |
invariant |
|---|
| 191 |
{ |
|---|
| 192 |
if (d) |
|---|
| 193 |
{ |
|---|
| 194 |
uint n = d.length; |
|---|
| 195 |
assert(n >= 2); // array must be sufficiently large (2 uints) |
|---|
| 196 |
int s = d[n-1]; |
|---|
| 197 |
assert((s == 0) || (s == -1)); // sign field may not contain rubbish |
|---|
| 198 |
if (n>2) |
|---|
| 199 |
{ |
|---|
| 200 |
assert(d[n-2] != s); // array must be minimal |
|---|
| 201 |
} |
|---|
| 202 |
} |
|---|
| 203 |
} |
|---|
| 204 |
|
|---|
| 205 |
public |
|---|
| 206 |
{ |
|---|
| 207 |
|
|---|
| 208 |
// -------- Constants -------- |
|---|
| 209 |
|
|---|
| 210 |
enum Round { TOWARD_ZERO, TOWARD_INFINITY, TOWARD_MINUS_INFINITY } |
|---|
| 211 |
|
|---|
| 212 |
static |
|---|
| 213 |
{ |
|---|
| 214 |
Int ZERO, ONE, TWO, MINUS_ONE; |
|---|
| 215 |
} |
|---|
| 216 |
|
|---|
| 217 |
static this() |
|---|
| 218 |
{ |
|---|
| 219 |
ZERO = new Int(0); |
|---|
| 220 |
ONE = new Int(1); |
|---|
| 221 |
TWO = new Int(2); |
|---|
| 222 |
MINUS_ONE = new Int(-1); |
|---|
| 223 |
} |
|---|
| 224 |
|
|---|
| 225 |
// -------- Constructors -------- |
|---|
| 226 |
|
|---|
| 227 |
// Construct from an int |
|---|
| 228 |
this(int n) |
|---|
| 229 |
{ |
|---|
| 230 |
d.length = 2; |
|---|
| 231 |
d[0] = n; |
|---|
| 232 |
d[1] = n < 0 ? -1U : 0; |
|---|
| 233 |
} |
|---|
| 234 |
|
|---|
| 235 |
static Int opCall(int n) { return new Int(n); } |
|---|
| 236 |
|
|---|
| 237 |
// Construct from a uint |
|---|
| 238 |
this(uint n) |
|---|
| 239 |
{ |
|---|
| 240 |
d.length = 2; |
|---|
| 241 |
d[0] = n; |
|---|
| 242 |
} |
|---|
| 243 |
|
|---|
| 244 |
static Int opCall(uint n) { return new Int(n); } |
|---|
| 245 |
|
|---|
| 246 |
// Construct from a long |
|---|
| 247 |
this(long n) |
|---|
| 248 |
{ |
|---|
| 249 |
d.length = 3; |
|---|
| 250 |
*(cast(ulong*)d) = n; |
|---|
| 251 |
d[2] = n < 0 ? -1U : 0; |
|---|
| 252 |
minimize(this); |
|---|
| 253 |
} |
|---|
| 254 |
|
|---|
| 255 |
static Int opCall(long n) { return new Int(n); } |
|---|
| 256 |
|
|---|
| 257 |
// Construct from a ulong |
|---|
| 258 |
this(ulong n) |
|---|
| 259 |
{ |
|---|
| 260 |
d.length = 3; |
|---|
| 261 |
*(cast(ulong*)d) = n; |
|---|
| 262 |
minimize(this); |
|---|
| 263 |
} |
|---|
| 264 |
|
|---|
| 265 |
static Int opCall(ulong n) { return new Int(n); } |
|---|
| 266 |
|
|---|
| 267 |
// Construct from a float |
|---|
| 268 |
this(float x) |
|---|
| 269 |
{ |
|---|
| 270 |
this(cast(real) x); |
|---|
| 271 |
} |
|---|
| 272 |
|
|---|
| 273 |
static Int opCall(float x) { return new Int(x); } |
|---|
| 274 |
|
|---|
| 275 |
// Construct from a double |
|---|
| 276 |
this(double x) |
|---|
| 277 |
{ |
|---|
| 278 |
this(cast(real) x); |
|---|
| 279 |
} |
|---|
| 280 |
|
|---|
| 281 |
static Int opCall(double x) { return new Int(x); } |
|---|
| 282 |
|
|---|
| 283 |
// Construct from a real |
|---|
| 284 |
this(real x) |
|---|
| 285 |
{ |
|---|
| 286 |
uint i; |
|---|
| 287 |
d.length = 4; |
|---|
| 288 |
bool sign = (x < 0); |
|---|
| 289 |
if (sign) x = -x; |
|---|
| 290 |
while (x > 0) |
|---|
| 291 |
{ |
|---|
| 292 |
real xq = floor(x / 4294967296.0); |
|---|
| 293 |
real xr = x - (xq * 4294967296.0); |
|---|
| 294 |
d[i++] = cast(uint) xr; |
|---|
| 295 |
if (i == d.length-1) d.length = d.length << 1; |
|---|
| 296 |
x = xq; |
|---|
| 297 |
} |
|---|
| 298 |
if (sign) |
|---|
| 299 |
{ |
|---|
| 300 |
bigintLLNeg(d, d, d.length); |
|---|
| 301 |
} |
|---|
| 302 |
minimize(this); |
|---|
| 303 |
} |
|---|
| 304 |
|
|---|
| 305 |
static Int opCall(real x) { return new Int(x); } |
|---|
| 306 |
|
|---|
| 307 |
// Construct from a string. |
|---|
| 308 |
this(char[] s) |
|---|
| 309 |
{ |
|---|
| 310 |
this(s, uint.max); |
|---|
| 311 |
} |
|---|
| 312 |
|
|---|
| 313 |
static Int opCall(char[] s) { return new Int(s); } |
|---|
| 314 |
|
|---|
| 315 |
this(char[] s, uint radix) |
|---|
| 316 |
{ |
|---|
| 317 |
bool isNegative = false; |
|---|
| 318 |
if (s.length > 1) |
|---|
| 319 |
{ |
|---|
| 320 |
if (s[0] == '+') |
|---|
| 321 |
{ |
|---|
| 322 |
s = s[1..s.length]; |
|---|
| 323 |
} |
|---|
| 324 |
else if (s[0] == '-') |
|---|
| 325 |
{ |
|---|
| 326 |
s = s[1..s.length]; |
|---|
| 327 |
isNegative = true; |
|---|
| 328 |
} |
|---|
| 329 |
} |
|---|
| 330 |
d = bigintFromString(s, radix); |
|---|
| 331 |
|
|---|
| 332 |
uint len = bigintLLMinimize(d, d.length); |
|---|
| 333 |
if (len == 0) |
|---|
| 334 |
{ |
|---|
| 335 |
d.length = 2; |
|---|
| 336 |
d[] = isNegative ? -1U : 0; |
|---|
| 337 |
} |
|---|
| 338 |
else |
|---|
| 339 |
{ |
|---|
| 340 |
d.length = len+1; |
|---|
| 341 |
} |
|---|
| 342 |
if (isNegative) |
|---|
| 343 |
{ |
|---|
| 344 |
bigintLLNeg(d, d, d.length); |
|---|
| 345 |
minimize(this); |
|---|
| 346 |
} |
|---|
| 347 |
} |
|---|
| 348 |
|
|---|
| 349 |
static Int opCall(char[] s, uint radix) { return new Int(s, radix); } |
|---|
| 350 |
|
|---|
| 351 |
// Construct from a uint array. This copies by value, not by reference; |
|---|
| 352 |
this(uint[] x, bool isNegative) |
|---|
| 353 |
{ |
|---|
| 354 |
d.length = x.length + 1; |
|---|
| 355 |
d[0..x.length] = x[0..x.length]; |
|---|
| 356 |
d[x.length] = isNegative ? -1U : 0; |
|---|
| 357 |
minimize(this); |
|---|
| 358 |
} |
|---|
| 359 |
|
|---|
| 360 |
static Int opCall(uint[] x, bool isNegative) { return new Int(x, isNegative); } |
|---|
| 361 |
|
|---|
| 362 |
// -------- Conversions -------- |
|---|
| 363 |
|
|---|
| 364 |
override |
|---|
| 365 |
{ |
|---|
| 366 |
char[] toString() |
|---|
| 367 |
out(s) |
|---|
| 368 |
{ |
|---|
| 369 |
assert(this == new Int(s)); |
|---|
| 370 |
} |
|---|
| 371 |
body |
|---|
| 372 |
{ |
|---|
| 373 |
return format(10, 0, 0, false, SignMode.NORMAL); |
|---|
| 374 |
} |
|---|
| 375 |
} |
|---|
| 376 |
|
|---|
| 377 |
char[] toHexString() |
|---|
| 378 |
out(s) |
|---|
| 379 |
{ |
|---|
| 380 |
assert(this == new Int(s,16)); |
|---|
| 381 |
} |
|---|
| 382 |
body |
|---|
| 383 |
{ |
|---|
| 384 |
return format(16, 0, 8, false, SignMode.NORMAL); |
|---|
| 385 |
} |
|---|
| 386 |
|
|---|
| 387 |
int toInt() |
|---|
| 388 |
{ |
|---|
| 389 |
if (isInt()) return d[0]; |
|---|
| 390 |
return (sign) ? int.min : int.max; |
|---|
| 391 |
} |
|---|
| 392 |
|
|---|
| 393 |
uint toUint() |
|---|
| 394 |
{ |
|---|
| 395 |
if (isUint()) return d[0]; |
|---|
| 396 |
return uint.max; |
|---|
| 397 |
} |
|---|
| 398 |
|
|---|
| 399 |
long toLong() |
|---|
| 400 |
{ |
|---|
| 401 |
if (isLong()) |
|---|
| 402 |
{ |
|---|
| 403 |
ulong lo = d[0]; |
|---|
| 404 |
ulong hi = d[1]; |
|---|
| 405 |
return (hi << 32) | lo; |
|---|
| 406 |
} |
|---|
| 407 |
return (sign) ? long.min : long.max; |
|---|
| 408 |
} |
|---|
| 409 |
|
|---|
| 410 |
ulong toUlong() |
|---|
| 411 |
{ |
|---|
| 412 |
if (isUlong()) |
|---|
| 413 |
{ |
|---|
| 414 |
ulong lo = d[0]; |
|---|
| 415 |
ulong hi = d[1]; |
|---|
| 416 |
return (hi << 32) | lo; |
|---|
| 417 |
} |
|---|
| 418 |
return ulong.max; |
|---|
| 419 |
} |
|---|
| 420 |
|
|---|
| 421 |
float toFloat() |
|---|
| 422 |
{ |
|---|
| 423 |
return toReal(); |
|---|
| 424 |
} |
|---|
| 425 |
|
|---|
| 426 |
double toDouble() |
|---|
| 427 |
{ |
|---|
| 428 |
return toReal(); |
|---|
| 429 |
} |
|---|
| 430 |
|
|---|
| 431 |
real toReal() |
|---|
| 432 |
{ |
|---|
| 433 |
if (sign) return -((-this).toReal()); |
|---|
| 434 |
real r = 0; |
|---|
| 435 |
for (uint i=0; i<end; ++i) |
|---|
| 436 |
{ |
|---|
| 437 |
r *= 4294967296.0; |
|---|
| 438 |
r += d[i]; |
|---|
| 439 |
} |
|---|
| 440 |
return r; |
|---|
| 441 |
} |
|---|
| 442 |
|
|---|
| 443 |
// -------- Tests -------- |
|---|
| 444 |
|
|---|
| 445 |
bool isInt() |
|---|
| 446 |
{ |
|---|
| 447 |
if (d.length > 2) return false; |
|---|
| 448 |
if (sign) |
|---|
| 449 |
{ |
|---|
| 450 |
return (d[0] >= 0x80000000); |
|---|
| 451 |
} |
|---|
| 452 |
else |
|---|
| 453 |
{ |
|---|
| 454 |
return (d[0] < 0x80000000); |
|---|
| 455 |
} |
|---|
| 456 |
} |
|---|
| 457 |
|
|---|
| 458 |
bool isUint() |
|---|
| 459 |
{ |
|---|
| 460 |
if (sign) return false; |
|---|
| 461 |
return (d.length == 2); |
|---|
| 462 |
} |
|---|
| 463 |
|
|---|
| 464 |
bool isLong() |
|---|
| 465 |
{ |
|---|
| 466 |
if (d.length > 3) return false; |
|---|
| 467 |
if (sign) |
|---|
| 468 |
{ |
|---|
| 469 |
return (d[d.length-2] >= 0x80000000); |
|---|
| 470 |
} |
|---|
| 471 |
else |
|---|
| 472 |
{ |
|---|
| 473 |
return (d[d.length-2] < 0x80000000); |
|---|
| 474 |
} |
|---|
| 475 |
} |
|---|
| 476 |
|
|---|
| 477 |
bool isUlong() |
|---|
| 478 |
{ |
|---|
| 479 |
if (sign) return false; |
|---|
| 480 |
return (d.length <= 3); |
|---|
| 481 |
} |
|---|
| 482 |
|
|---|
| 483 |
override |
|---|
| 484 |
{ |
|---|
| 485 |
int /*I wish this was bool*/ opEquals(Object obj) |
|---|
| 486 |
{ |
|---|
| 487 |
Int y = cast(Int) obj; |
|---|
| 488 |
assert(y); |
|---|
| 489 |
return d == y.d; |
|---|
| 490 |
} |
|---|
| 491 |
} |
|---|
| 492 |
|
|---|
| 493 |
int /*I wish this was bool*/ opEquals(int n) |
|---|
| 494 |
{ |
|---|
| 495 |
return isInt() ? (n == d[0]) : 0; |
|---|
| 496 |
} |
|---|
| 497 |
|
|---|
| 498 |
int /*I wish this was bool*/ opEquals(uint n) |
|---|
| 499 |
{ |
|---|
| 500 |
return isUint() ? (n == d[0]) : 0; |
|---|
| 501 |
} |
|---|
| 502 |
|
|---|
| 503 |
override |
|---|
| 504 |
{ |
|---|
| 505 |
int opCmp(Object obj) |
|---|
| 506 |
{ |
|---|
| 507 |
Int y = cast(Int) obj; |
|---|
| 508 |
assert(y); |
|---|
| 509 |
|
|---|
| 510 |
Int x = this; |
|---|
| 511 |
if (x === y) return 0; |
|---|
| 512 |
int xSign = x.sign; |
|---|
| 513 |
int ySign = y.sign; |
|---|
| 514 |
if (xSign < ySign) return -1; |
|---|
| 515 |
if (xSign > ySign) return 1; |
|---|
| 516 |
|
|---|
| 517 |
int r; |
|---|
| 518 |
int n = x.d.length; |
|---|
| 519 |
if (x.d.length > y.d.length) |
|---|
| 520 |
{ |
|---|
| 521 |
n = y.d.length; |
|---|
| 522 |
r = bigintLLCmpAll(&x.d[y.d.length], y.sign, x.d.length - y.d.length); |
|---|
| 523 |
if (r < 0) return -1; |
|---|
| 524 |
if (r > 0) return 1; |
|---|
| 525 |
} |
|---|
| 526 |
if (x.d.length < y.d.length) |
|---|
| 527 |
{ |
|---|
| 528 |
r = bigintLLCmpAll(x.sign, &y.d[x.d.length], y.d.length - x.d.length); |
|---|
| 529 |
if (r < 0) return -1; |
|---|
| 530 |
if (r > 0) return 1; |
|---|
| 531 |
} |
|---|
| 532 |
r = bigintLLCmp(x.d, y.d, n); |
|---|
| 533 |
if (r < 0) return -1; |
|---|
| 534 |
if (r > 0) return 1; |
|---|
| 535 |
return 0; |
|---|
| 536 |
} |
|---|
| 537 |
} |
|---|
| 538 |
|
|---|
| 539 |
int opCmp(int y) |
|---|
| 540 |
{ |
|---|
| 541 |
if (isInt()) |
|---|
| 542 |
{ |
|---|
| 543 |
int x = d[0]; |
|---|
| 544 |
if (x == y) return 0; |
|---|
| 545 |
return (x < y) ? -1 : 1; |
|---|
| 546 |
} |
|---|
| 547 |
else |
|---|
| 548 |
{ |
|---|
| 549 |
return opCmp(new Int(y)); |
|---|
| 550 |
} |
|---|
| 551 |
} |
|---|
| 552 |
|
|---|
| 553 |
int opCmp(uint y) |
|---|
| 554 |
{ |
|---|
| 555 |
if (isUint()) |
|---|
| 556 |
{ |
|---|
| 557 |
uint x = d[0]; |
|---|
| 558 |
if (x == y) return 0; |
|---|
| 559 |
return (x < y) ? -1 : 1; |
|---|
| 560 |
} |
|---|
| 561 |
else |
|---|
| 56 |
|---|