src/share/classes/sun/misc/FDBigInteger.java

Print this page
rev 7487 : 7192954: Fix Float.parseFloat to round correctly and preserve monotonicity.
4396272: Parsing doubles fails to follow IEEE for largest decimal that should yield 0
7039391: Use Math.ulp in FloatingDecimal
Summary: Correct rounding and monotonicity problems in floats and doubles
Reviewed-by: martin
Contributed-by: Dmitry Nadezhin <dmitry.nadezhin@oracle.com>, Louis Wasserman <lowasser@google.com>


 765      * @return This <code>FDBigInteger</code> less the subtrahend.
 766      */
 767     /*@
 768      @ requires this.isImmutable;
 769      @ requires this.value() >= subtrahend.value();
 770      @ assignable \nothing;
 771      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 772      @
 773      @  also
 774      @
 775      @ requires !subtrahend.isImmutable;
 776      @ requires this.value() >= subtrahend.value();
 777      @ assignable this.nWords, this.offset, this.data, this.data[*];
 778      @ ensures \result == this;
 779      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 780      @*/
 781     public FDBigInteger leftInplaceSub(FDBigInteger subtrahend) {
 782         assert this.size() >= subtrahend.size() : "result should be positive";
 783         FDBigInteger minuend;
 784         if (this.isImmutable) {
 785             minuend = new FDBigInteger(this.data, this.offset);
 786         } else {
 787             minuend = this;
 788         }
 789         int offsetDiff = subtrahend.offset - minuend.offset;
 790         int[] sData = subtrahend.data;
 791         int[] mData = minuend.data;
 792         int subLen = subtrahend.nWords;
 793         int minLen = minuend.nWords;
 794         if (offsetDiff < 0) {
 795             // need to expand minuend
 796             int rLen = minLen - offsetDiff;
 797             if (rLen < mData.length) {
 798                 System.arraycopy(mData, 0, mData, -offsetDiff, minLen);
 799                 Arrays.fill(mData, 0, -offsetDiff, 0);
 800             } else {
 801                 int[] r = new int[rLen];
 802                 System.arraycopy(mData, 0, r, -offsetDiff, minLen);
 803                 minuend.data = mData = r;
 804             }
 805             minuend.offset = subtrahend.offset;


 834      * @return This <code>FDBigInteger</code> less the subtrahend.
 835      */
 836     /*@
 837      @ requires subtrahend.isImmutable;
 838      @ requires this.value() >= subtrahend.value();
 839      @ assignable \nothing;
 840      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 841      @
 842      @  also
 843      @
 844      @ requires !subtrahend.isImmutable;
 845      @ requires this.value() >= subtrahend.value();
 846      @ assignable subtrahend.nWords, subtrahend.offset, subtrahend.data, subtrahend.data[*];
 847      @ ensures \result == subtrahend;
 848      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 849      @*/
 850     public FDBigInteger rightInplaceSub(FDBigInteger subtrahend) {
 851         assert this.size() >= subtrahend.size() : "result should be positive";
 852         FDBigInteger minuend = this;
 853         if (subtrahend.isImmutable) {
 854             subtrahend = new FDBigInteger(subtrahend.data, subtrahend.offset);
 855         }
 856         int offsetDiff = minuend.offset - subtrahend.offset;
 857         int[] sData = subtrahend.data;
 858         int[] mData = minuend.data;
 859         int subLen = subtrahend.nWords;
 860         int minLen = minuend.nWords;
 861         if (offsetDiff < 0) {
 862             int rLen = minLen;
 863             if (rLen < sData.length) {
 864                 System.arraycopy(sData, 0, sData, -offsetDiff, subLen);
 865                 Arrays.fill(sData, 0, -offsetDiff, 0);
 866             } else {
 867                 int[] r = new int[rLen];
 868                 System.arraycopy(sData, 0, r, -offsetDiff, subLen);
 869                 subtrahend.data = sData = r;
 870             }
 871             subtrahend.offset = minuend.offset;
 872             subLen -= offsetDiff;
 873             offsetDiff = 0;
 874         } else {




 765      * @return This <code>FDBigInteger</code> less the subtrahend.
 766      */
 767     /*@
 768      @ requires this.isImmutable;
 769      @ requires this.value() >= subtrahend.value();
 770      @ assignable \nothing;
 771      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 772      @
 773      @  also
 774      @
 775      @ requires !subtrahend.isImmutable;
 776      @ requires this.value() >= subtrahend.value();
 777      @ assignable this.nWords, this.offset, this.data, this.data[*];
 778      @ ensures \result == this;
 779      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 780      @*/
 781     public FDBigInteger leftInplaceSub(FDBigInteger subtrahend) {
 782         assert this.size() >= subtrahend.size() : "result should be positive";
 783         FDBigInteger minuend;
 784         if (this.isImmutable) {
 785             minuend = new FDBigInteger(this.data.clone(), this.offset);
 786         } else {
 787             minuend = this;
 788         }
 789         int offsetDiff = subtrahend.offset - minuend.offset;
 790         int[] sData = subtrahend.data;
 791         int[] mData = minuend.data;
 792         int subLen = subtrahend.nWords;
 793         int minLen = minuend.nWords;
 794         if (offsetDiff < 0) {
 795             // need to expand minuend
 796             int rLen = minLen - offsetDiff;
 797             if (rLen < mData.length) {
 798                 System.arraycopy(mData, 0, mData, -offsetDiff, minLen);
 799                 Arrays.fill(mData, 0, -offsetDiff, 0);
 800             } else {
 801                 int[] r = new int[rLen];
 802                 System.arraycopy(mData, 0, r, -offsetDiff, minLen);
 803                 minuend.data = mData = r;
 804             }
 805             minuend.offset = subtrahend.offset;


 834      * @return This <code>FDBigInteger</code> less the subtrahend.
 835      */
 836     /*@
 837      @ requires subtrahend.isImmutable;
 838      @ requires this.value() >= subtrahend.value();
 839      @ assignable \nothing;
 840      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 841      @
 842      @  also
 843      @
 844      @ requires !subtrahend.isImmutable;
 845      @ requires this.value() >= subtrahend.value();
 846      @ assignable subtrahend.nWords, subtrahend.offset, subtrahend.data, subtrahend.data[*];
 847      @ ensures \result == subtrahend;
 848      @ ensures \result.value() == \old(this.value() - subtrahend.value());
 849      @*/
 850     public FDBigInteger rightInplaceSub(FDBigInteger subtrahend) {
 851         assert this.size() >= subtrahend.size() : "result should be positive";
 852         FDBigInteger minuend = this;
 853         if (subtrahend.isImmutable) {
 854             subtrahend = new FDBigInteger(subtrahend.data.clone(), subtrahend.offset);
 855         }
 856         int offsetDiff = minuend.offset - subtrahend.offset;
 857         int[] sData = subtrahend.data;
 858         int[] mData = minuend.data;
 859         int subLen = subtrahend.nWords;
 860         int minLen = minuend.nWords;
 861         if (offsetDiff < 0) {
 862             int rLen = minLen;
 863             if (rLen < sData.length) {
 864                 System.arraycopy(sData, 0, sData, -offsetDiff, subLen);
 865                 Arrays.fill(sData, 0, -offsetDiff, 0);
 866             } else {
 867                 int[] r = new int[rLen];
 868                 System.arraycopy(sData, 0, r, -offsetDiff, subLen);
 869                 subtrahend.data = sData = r;
 870             }
 871             subtrahend.offset = minuend.offset;
 872             subLen -= offsetDiff;
 873             offsetDiff = 0;
 874         } else {