## Revision 34a8541f

#### Added by Michael Kayalmost 13 years ago

Fix bug 2510104 - multiplying large integers

View differences:

latest9.1/bj/net/sf/saxon/value/Int64Value.java
539 539
```    public IntegerValue times(IntegerValue other) {
```
540 540
```        // if either of the values is large, we use BigInteger arithmetic to be on the safe side
```
541 541
```        if (other instanceof Int64Value) {
```
542
```            long topa = value >> 32;
```
543
```            if (topa != 0 && topa != 0xffffffff) {
```
544
```                return new BigIntegerValue(value).times(new BigIntegerValue(((Int64Value)other).value));
```
545
```            }
```
546
```            long topb = (((Int64Value)other).value >> 32);
```
547
```            if (topb != 0 && topb != 0xffffffff) {
```
542
```            if (isLong() || ((Int64Value)other).isLong()) {
```
548 543
```                return new BigIntegerValue(value).times(new BigIntegerValue(((Int64Value)other).value));
```
544
```            } else {
```
545
```                return makeIntegerValue(value * ((Int64Value)other).value);
```
549 546
```            }
```
550
```            return makeIntegerValue(value * ((Int64Value)other).value);
```
551 547
```        } else {
```
552 548
```            return new BigIntegerValue(value).times(other);
```
553 549
```        }
```
......
560 556
```    public NumericValue div(IntegerValue other) throws XPathException {
```
561 557
```        // if either of the values is large, we use BigInteger arithmetic to be on the safe side
```
562 558
```        if (other instanceof Int64Value) {
```
563
```            long topa = value >> 32;
```
564
```            if (topa != 0 && topa != 0xffffffff) {
```
565
```                return new BigIntegerValue(value).div(new BigIntegerValue(((Int64Value)other).value));
```
559
```            long quotient = ((Int64Value)other).value;
```
560
```            if (quotient == 0) {
```
561
```                throw new XPathException("Integer division by zero", "FOAR0001");
```
566 562
```            }
```
567
```            long topb = ((Int64Value)other).value >> 32;
```
568
```            if (topb != 0 && topb != 0xffffffff) {
```
569
```                return new BigIntegerValue(value).div(new BigIntegerValue(((Int64Value)other).value));
```
563
```            if (isLong() || ((Int64Value)other).isLong()) {
```
564
```                return new BigIntegerValue(value).div(new BigIntegerValue(quotient));
```
570 565
```            }
```
566

571 567
```            // the result of dividing two integers is a decimal; but if
```
572 568
```            // one divides exactly by the other, we implement it as an integer
```
573
```            long quotient = ((Int64Value) other).value;
```
574
```            if (quotient == 0) {
```
575
```                throw new XPathException("Integer division by zero", "FOAR0001");
```
576
```            }
```
577 569
```            if (value % quotient == 0) {
```
578 570
```                return makeIntegerValue(value / quotient);
```
579
```            }
```
580
```            return (NumericValue)Calculator.DECIMAL_DECIMAL[Calculator.DIV].compute(
```
571
```            } else {
```
572
```                return (NumericValue)Calculator.DECIMAL_DECIMAL[Calculator.DIV].compute(
```
581 573
```                            new DecimalValue(value), new DecimalValue(quotient), null);
```
574
```            }
```
582 575
```        } else {
```
583 576
```            return new BigIntegerValue(value).div(other);
```
584 577
```        }
```
......
591 584
```    public IntegerValue mod(IntegerValue other) throws XPathException {
```
592 585
```        // if either of the values is large, we use BigInteger arithmetic to be on the safe side
```
593 586
```        if (other instanceof Int64Value) {
```
594
```            long topa = value >> 32;
```
595
```            if (topa != 0 && topa != 0xffffffff) {
```
596
```                return new BigIntegerValue(value).mod(new BigIntegerValue(((Int64Value)other).value));
```
597
```            }
```
598 587
```            long quotient = ((Int64Value) other).value;
```
599 588
```            if (quotient == 0) {
```
600 589
```                throw new XPathException("Integer modulo zero", "FOAR0001");
```
601 590
```            }
```
602
```            long topb = quotient >> 32;
```
603
```            if (topb != 0 && topb != 0xffffffff) {
```
591
```            if (isLong() || ((Int64Value)other).isLong()) {
```
604 592
```                return new BigIntegerValue(value).mod(new BigIntegerValue(((Int64Value)other).value));
```
593
```            } else {
```
594
```                return makeIntegerValue(value % quotient);
```
605 595
```            }
```
606
```            return makeIntegerValue(value % quotient);
```
607 596
```        } else {
```
608 597
```            return new BigIntegerValue(value).mod(other);
```
609 598
```        }
```
......
616 605
```    public IntegerValue idiv(IntegerValue other) throws XPathException {
```
617 606
```       // if either of the values is large, we use BigInteger arithmetic to be on the safe side
```
618 607
```        if (other instanceof Int64Value) {
```
619
```            long topa = (value >> 32);
```
620
```            if (topa != 0 && topa != 0xffffffff) {
```
621
```                return new BigIntegerValue(value).idiv(new BigIntegerValue(((Int64Value)other).value));
```
622
```            }
```
623
```            long topb = (((Int64Value)other).value >> 32);
```
624
```            if (topb != 0 && topb != 0xffffffff) {
```
608
```            if (isLong() || ((Int64Value)other).isLong()) {
```
625 609
```                return new BigIntegerValue(value).idiv(new BigIntegerValue(((Int64Value)other).value));
```
626 610
```            }
```
627 611
```            try {
```
......
637 621
```            }
```
638 622
```        } else {
```
639 623
```            return new BigIntegerValue(value).idiv(other);
```
640
```        }
```
624
```        }
```
625
```    }
```
626

627
```    /**
```
628
```     * Test whether this value needs a long to hold it. Specifically, whether
```
629
```     * the absolute value is > 2^31.
```
630
```     */
```
631

632
```    private boolean isLong() {
```
633
```        long top = value >> 31;
```
634
```        return top != 0 && top != 0x1ffffffffL;
```
641 635
```    }
```
642 636

643 637
```    /**
```

Also available in: Unified diff