Bladeren bron

重写收银端商品数量改变逻辑,新增BigNumber计算工具类

lhm 3 jaren geleden
bovenliggende
commit
c7e54d5f39

+ 6 - 2
kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java

@@ -1370,9 +1370,13 @@ public class OrderController {
     @PostMapping("/calculateOrderDiscountPrice")
     public R calculateOrderDiscountPrice(@RequestBody CalculateOrderDiscountPriceVo calculateOrderDiscountPriceVo) {
 
-        List<GoodsDetailsDto> queryGoodsVos = orderService.calculateOrderDiscountPrice(calculateOrderDiscountPriceVo);
+        try {
+            List<GoodsDetailsDto> queryGoodsVos = orderService.calculateOrderDiscountPrice(calculateOrderDiscountPriceVo);
+            return R.ok().put("goodsList", queryGoodsVos);
+        } catch (Exception e) {
+            return R.error("计算出错!请联系管理员!" + e.getMessage());
+        }
 
-        return R.ok().put("goodsList", queryGoodsVos);
     }
 
 

+ 7 - 9
kmall-admin/src/main/java/com/kmall/admin/service/impl/OrderServiceImpl.java

@@ -4020,9 +4020,7 @@ public class OrderServiceImpl implements OrderService {
                 // 无活动情况,实际支付价 = 零售价
                 BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity , goodsEntity.getRetailPrice(), goodsService).setScale(3,RoundingMode.HALF_UP);
                 // 预估税
-                goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
-                // TODO 测试用
-                goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
+                goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
             }
             return goodsDetailsDtos;
         }
@@ -4066,7 +4064,7 @@ public class OrderServiceImpl implements OrderService {
                                     BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
                                     // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
                                     BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
-                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                     goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
                                     goodsDetailsDto.setActivity("满赠商品");
                                     goodsDetailsDto.setGiftNumber(mkActivitiesFullGiftEntity.getGiftNumber());
@@ -4093,7 +4091,7 @@ public class OrderServiceImpl implements OrderService {
                                     BeanUtils.copyProperties(goodsEntity, goodsDetailsDto);
                                     // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
                                     BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
-                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                     goodsDetailsDto.setActualPaymentAmount(BigDecimal.ZERO);
                                     goodsDetailsDto.setActivity("满赠商品");
                                     goodsDetailsDto.setGiftNumber(mkActivitiesFullGiftEntity.getGiftNumber());
@@ -4141,7 +4139,7 @@ public class OrderServiceImpl implements OrderService {
                                     // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
                                     BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
                                     goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
-                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                     goodsDetailsDto.setActivity("优惠券活动");
                                     goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
                                     goodsDetailsDtos.add(goodsDetailsDto);
@@ -4164,7 +4162,7 @@ public class OrderServiceImpl implements OrderService {
                                     // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
                                     BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
                                     goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
-                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                    goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                     goodsDetailsDto.setActivity("优惠券活动");
                                     goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
                                     goodsDetailsDtos.add(goodsDetailsDto);
@@ -4192,7 +4190,7 @@ public class OrderServiceImpl implements OrderService {
                                         // 除了限时促销(需要向海关备案),其它活动都拿海关备案价来算税款
                                         BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, goodsEntity.getRetailPrice(), goodsService).setScale(3, RoundingMode.HALF_UP);
                                         goodsDetailsDto.setActualPaymentAmount(discountAfterPrice);
-                                        goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                        goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                         goodsDetailsDto.setActivity("优惠券活动");
                                         goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(discountAfterPrice));
                                         goodsDetailsDtos.add(goodsDetailsDto);
@@ -4229,7 +4227,7 @@ public class OrderServiceImpl implements OrderService {
                                 BigDecimal tax = CalculateTax.calculateFinalTax(goodsEntity, activityPrice, goodsService).setScale(3, RoundingMode.HALF_UP);
                                 BeanUtils.copyProperties(goodsDetailsDto, goodsEntity);
                                 goodsDetailsDto.setActualPaymentAmount(activityPrice);
-                                goodsDetailsDto.setGoodstaxes(String.valueOf(tax));
+                                goodsDetailsDto.setGoodstaxes(String.valueOf(tax.multiply(new BigDecimal(goodsDetailsDto.getSellVolume()))));
                                 goodsDetailsDto.setActivity("限时促销");
                                 goodsDetailsDto.setDiscountedPrice(retailPrice.subtract(activityPrice));
                                 goodsDetailsDtos.add(goodsDetailsDto);

+ 1 - 0
kmall-admin/src/main/webapp/WEB-INF/page/sale/sale.html

@@ -529,6 +529,7 @@
     };
 </script>
 <script src="${rc.contextPath}/statics/dist/js7_jsAddress.js"></script>
+<script src="${rc.contextPath}/statics/libs/bignumber.js"></script>
 <script src="${rc.contextPath}/js/sale/sale.js?_${date.systemTime}"></script>
 <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
 <script src="${rc.contextPath}/statics/libs/bootstrap.min.js"></script>

+ 83 - 34
kmall-admin/src/main/webapp/js/sale/sale.js

@@ -743,12 +743,15 @@ let vm = new Vue({
             // 增加数量
             for(var i = 0 ; i < this.goodsList.length ; i++){
                 if(this.goodsList[i].id == value){
-                    var goodsDetails = JSON.parse(JSON.stringify(vm.goodsMap.get(this.goodsList[i].goodsSn)));
-                    calculateGoodsByMj(goodsDetails,"add");
+                    // var goodsDetails = JSON.parse(JSON.stringify(vm.goodsMap.get(this.goodsList[i].goodsSn)));
+                    let goodsDetails = JSON.parse(JSON.stringify(vm.goodsList[i]));
+                    console.log("加法 goods detail =====>" + JSON.stringify(goodsDetails));
+                    /*calculateGoodsByMj(goodsDetails,"add");
                     calculateGoodsByMysy(goodsDetails,"add");
-                    calculateGoodsByHalfPrice(goodsDetails,"add");
+                    calculateGoodsByHalfPrice(goodsDetails,"add");*/
                     // calculateGoodsByMz(goodsDetails,"add");
-                    handle(goodsDetails,"add");
+                    handleSellVolume(goodsDetails, "add");
+                    // handle(goodsDetails,"add");
                     break;
                 }
             }
@@ -758,16 +761,14 @@ let vm = new Vue({
             for(var i = 0 ; i < this.goodsList.length ; i++){
                 if(this.goodsList[i].id == value){
                     // 获取当前购物车的数量
-                    var g = JSON.parse(JSON.stringify(this.goodsList[i]));
-
-                    console.log(g);
-                    var goodsDetails = JSON.parse(JSON.stringify(vm.goodsMap.get(this.goodsList[i].goodsSn)));
-                    if(g.sellVolume === 1){
+                    let goodsDetails = JSON.parse(JSON.stringify(vm.goodsList[i]));
+                    console.log("减法 goods detail =====>" + JSON.stringify(goodsDetails));
+                    if(goodsDetails.sellVolume === 1){
                         alert("数量至少为1个");
                         return ;
                     }
                     // 如果不为空,证明减的是买A送B中的B,这时候要还原赠送资格跟B的扣减
-                    var freeMap = vm.freeBardcode.get(goodsDetails.prodBarcode);
+                    /*var freeMap = vm.freeBardcode.get(goodsDetails.prodBarcode);
                     if((freeMap || freeMap == 0) && g.actualPaymentAmount == 0){
                         vm.freeBardcode.set(goodsDetails.prodBarcode,freeMap + 1);
                         goodsDetails.sellVolume = -1;
@@ -786,9 +787,9 @@ let vm = new Vue({
                         goodsDetails.discountedPrice = -goodsDetails.discountedPrice;
                         goodsDetails.goodstaxes = - goodsDetails.goodstaxes;
                         goodsDetails.retailPrice = - goodsDetails.retailPrice;
-                    }
-
-                    handle(goodsDetails,"minus");
+                    }*/
+                    handleSellVolume(goodsDetails, "minus");
+                    // handle(goodsDetails,"minus");
                     break;
                 }
             }
@@ -946,6 +947,9 @@ let vm = new Vue({
         // 计算优惠价格,返回订单详情数据
         calculateOrderPriceSubmit : function () {
             console.log("11111");
+
+            console.log("点击计算=====>" + JSON.stringify(vm.goodsList));
+
             var couponBarCode = vm.$refs.couponBarCode;
             if (couponBarCode === null || couponBarCode === '') {
                 alert("无会员码,不能参加积分抵扣活动!\n计算中...");
@@ -1785,16 +1789,18 @@ function removeByValue(arr, val) {
 function handle(goodsDetails,operatorType){
     vm.goodsDetail = true;
     // goodsDetails.sellVolume = 1;
+    console.log("goodsDetails=====>" + JSON.stringify(goodsDetails));
     goodsDetails.id = vm.index;
+    console.log("vm.index====>" + vm.index);
     if(!vm.goodsList[vm.index]){
         vm.index = vm.max;
     }
+    console.log("vm.goodsList[vm.index]=====>" + vm.goodsList[vm.index]);
     vm.max++;
     goodsDetails.goodsDesc = "";
 
-
     // 判断当前商品是否是赠品
-        var freeMap = vm.freeBardcode.get(goodsDetails.prodBarcode);
+        /*var freeMap = vm.freeBardcode.get(goodsDetails.prodBarcode);
         if(freeMap && "minus" != operatorType){
             goodsDetails.actualPaymentAmount = 0;
             goodsDetails.discountedPrice = goodsDetails.retailPrice;
@@ -1805,7 +1811,7 @@ function handle(goodsDetails,operatorType){
                 for(var i = 0 ; i < vm.goodsList.length ; i++){
                     var shopcartGoods = vm.goodsList[i];
                     var shopcartFree = vm.freeBardcode.get(shopcartGoods.prodBarcode);
-                    if(shopcartFree /*&& shopcartGoods.actualPaymentAmount*/){
+                    if(shopcartFree /!*&& shopcartGoods.actualPaymentAmount*!/){
                         // if("minus" != operatorType){
                             var shopcartSellNum = shopcartGoods.sellVolume;
                             if(shopcartFree > shopcartSellNum){
@@ -1841,13 +1847,7 @@ function handle(goodsDetails,operatorType){
 
                 }
             }
-        }
-
-
-
-
-
-
+        }*/
 
     goodsDetails.discountedPrice =  Math.round(goodsDetails.discountedPrice * 100) / 100;
     goodsDetails.actualPaymentAmount =  Math.round(goodsDetails.actualPaymentAmount * 100) / 100;
@@ -1894,10 +1894,8 @@ function handle(goodsDetails,operatorType){
 
     if("minus" == operatorType){
         vm.totalCount = vm.totalCount - 1;
-        vm.goodsList[vm.index].sellVolume -= 1;
     }else{
         vm.totalCount = vm.totalCount + 1;
-        vm.goodsList[vm.index].sellVolume += 1;
     }
 
     if(vm.reduceMoney > 0){
@@ -1920,6 +1918,9 @@ function handle(goodsDetails,operatorType){
     vm.discountedPrice =  Math.round(vm.discountedPrice * 100) / 100;
     vm.actualPrice =  Math.round(vm.actualPrice * 100) / 100;
     vm.showReduceMoney =  Math.round(vm.showReduceMoney * 100) / 100;
+
+
+    console.log("goodsDetails after=====>" + JSON.stringify(vm.goodsList));
 }
 
 // 下单处理
@@ -2002,7 +2003,7 @@ function toRefund(){
     })
 }
 // 计算当前购物栏商品优惠价格
-function calculateOrderPrice() {
+calculateOrderPrice = function() {
     vm.machineCode = sessionStorage.getItem("machineCode");
     var cmbCity = $('#cmbCity').val();
     var cmbProvince = $('#cmbProvince').val();
@@ -2012,7 +2013,7 @@ function calculateOrderPrice() {
     console.log(vm.machineCode);
     var param = {
         'storeId': sessionStorage.getItem("storeId"),
-        'goodsList' : vm.calGoodsList
+        'goodsList' : vm.goodsList
     };
 
     console.log("请求参数===>" + JSON.stringify(param));
@@ -2023,22 +2024,19 @@ function calculateOrderPrice() {
         contentType: "application/json",
         data: JSON.stringify(param),
         success: function (r) {
-            if (r.code == 0) {
+            if (r.code === 0) {
                 let calGoodsList = r.goodsList;
                 // 更新购物栏中数据
                 console.log("返回====>" + JSON.stringify(r));
                 console.log("计算前数据===>" + JSON.stringify(vm.goodsList));
                 vm.goodsList.clear();
-                calGoodsList.forEach(goods => {
-                    goods.sellVolume = $("#")
-                    vm.goodsList.push(goods);
-                });
+                calGoodsList.forEach(goods => vm.goodsList.push(goods));
                 console.log("计算后数据===>" + JSON.stringify(calGoodsList));
                 console.log("替换后数据===>" + JSON.stringify(vm.goodsList));
 
                 $("#calculateOrderPriceDialog").modal('hide');
-            } else if (r.code == 500) {
-                alert(r.msg)
+            } else if (r.code === 500) {
+                alert(r.msg);
             } else {
                 alert("计算失败,请联系管理员");
             }
@@ -2046,4 +2044,55 @@ function calculateOrderPrice() {
     });
 }
 
+/**
+ * 处理加减按钮操作
+ * @param currentGoodsDetail    当前操作的商品详情
+ * @param type                  类型,add:加 minus:减
+ */
+handleSellVolume = function (currentGoodsDetail, type) {
+    console.log("处理前商品详情=====>" + JSON.stringify(currentGoodsDetail));
+    // 当前未被处理的商品数量
+    let number = currentGoodsDetail.sellVolume;
+    // 当前商品应支付金额
+    let currentActualPaymentAmount = new BigNumber(currentGoodsDetail.actualPaymentAmount);
+    // 当前商品税款
+    let currentGoodsTax = new BigNumber(currentGoodsDetail.goodstaxes);
+    // 当前商品零售价
+    let retailPrice = new BigNumber(currentGoodsDetail.retailPrice);
+    // 单个商品时的税款
+    let singleTax = currentGoodsTax.divide(number);
+    // 单个商品时的应支付金额
+    let singleActualPaymentAmount = currentActualPaymentAmount.divide(number);
+
+    // 当前总价
+    let currentTotalPrice = new BigNumber(vm.totalPrice);
+    // 当前实际支付价
+    let currentActualPrice = new BigNumber(vm.actualPrice);
+    if ('add' === type) {
+        currentGoodsDetail.sellVolume += 1;
+        currentGoodsDetail.goodstaxes = currentGoodsTax.add(singleTax).toString();
+        currentGoodsDetail.actualPaymentAmount = currentActualPaymentAmount.add(singleActualPaymentAmount).toString();
+        vm.totalCount += 1;
+        vm.totalPrice = currentTotalPrice.add(retailPrice).toString();
+        vm.actualPrice = currentActualPrice.add(singleActualPaymentAmount).toString();
+    } else {
+        currentGoodsDetail.sellVolume -= 1;
+        currentGoodsDetail.goodstaxes = currentGoodsTax.subtract(singleTax).toString();
+        currentGoodsDetail.actualPaymentAmount = currentActualPaymentAmount.subtract(singleActualPaymentAmount).toString();
+        vm.totalCount -= 1;
+        vm.totalPrice = currentTotalPrice.subtract(retailPrice).toString();
+        vm.actualPrice = currentActualPrice.subtract(singleActualPaymentAmount).toString();
+    }
+
+    for (let i = 0; i < vm.goodsList.length; i++) {
+        let goods = vm.goodsList[i];
+        if (currentGoodsDetail.prodBarcode === goods.prodBarcode && currentGoodsDetail.goodsSn === goods.goodsSn) {
+            let splice = vm.goodsList.splice(i, 1, currentGoodsDetail);
+            console.log("被删除的元素====>" + JSON.stringify(splice));
+        }
+    }
+
+    console.log("处理后商品详情=====>" + JSON.stringify(currentGoodsDetail))
+}
+
 

+ 138 - 0
kmall-admin/src/main/webapp/statics/libs/bignumber.js

@@ -0,0 +1,138 @@
+//+ Jonas Raoni Soares Silva
+//@ http://jsfromhell.com/classes/bignumber [rev. #4]
+
+BigNumber = function(n, p, r){
+	var o = this, i;
+	if(n instanceof BigNumber){
+		for(i in {precision: 0, roundType: 0, _s: 0, _f: 0}) o[i] = n[i];
+		o._d = n._d.slice();
+		return;
+	}
+	o.precision = isNaN(p = Math.abs(p)) ? BigNumber.defaultPrecision : p;
+	o.roundType = isNaN(r = Math.abs(r)) ? BigNumber.defaultRoundType : r;
+	o._s = (n += "").charAt(0) == "-";
+	o._f = ((n = n.replace(/[^\d.]/g, "").split(".", 2))[0] = n[0].replace(/^0+/, "") || "0").length;
+	for(i = (n = o._d = (n.join("") || "0").split("")).length; i; n[--i] = +n[i]);
+	o.round();
+};
+with({$: BigNumber, o: BigNumber.prototype}){
+	$.ROUND_HALF_EVEN = ($.ROUND_HALF_DOWN = ($.ROUND_HALF_UP = ($.ROUND_FLOOR = ($.ROUND_CEIL = ($.ROUND_DOWN = ($.ROUND_UP = 0) + 1) + 1) + 1) + 1) + 1) + 1;
+	$.defaultPrecision = 40;
+	$.defaultRoundType = $.ROUND_HALF_UP;
+	o.add = function(n){
+		if(this._s != (n = new BigNumber(n))._s)
+			return n._s ^= 1, this.subtract(n);
+		var o = new BigNumber(this), a = o._d, b = n._d, la = o._f,
+		lb = n._f, n = Math.max(la, lb), i, r;
+		la != lb && ((lb = la - lb) > 0 ? o._zeroes(b, lb, 1) : o._zeroes(a, -lb, 1));
+		i = (la = a.length) == (lb = b.length) ? a.length : ((lb = la - lb) > 0 ? o._zeroes(b, lb) : o._zeroes(a, -lb)).length;
+		for(r = 0; i; r = (a[--i] = a[i] + b[i] + r) / 10 >>> 0, a[i] %= 10);
+		return r && ++n && a.unshift(r), o._f = n, o.round();
+	};
+	o.subtract = function(n){
+		if(this._s != (n = new BigNumber(n))._s)
+			return n._s ^= 1, this.add(n);
+		var o = new BigNumber(this), c = o.abs().compare(n.abs()) + 1, a = c ? o : n, b = c ? n : o, la = a._f, lb = b._f, d = la, i, j;
+		a = a._d, b = b._d, la != lb && ((lb = la - lb) > 0 ? o._zeroes(b, lb, 1) : o._zeroes(a, -lb, 1));
+		for(i = (la = a.length) == (lb = b.length) ? a.length : ((lb = la - lb) > 0 ? o._zeroes(b, lb) : o._zeroes(a, -lb)).length; i;){
+			if(a[--i] < b[i]){
+				for(j = i; j && !a[--j]; a[j] = 9);
+				--a[j], a[i] += 10;
+			}
+			b[i] = a[i] - b[i];
+		}
+		return c || (o._s ^= 1), o._f = d, o._d = b, o.round();
+	};
+	o.multiply = function(n){
+		var o = new BigNumber(this), r = o._d.length >= (n = new BigNumber(n))._d.length, a = (r ? o : n)._d,
+		b = (r ? n : o)._d, la = a.length, lb = b.length, x = new BigNumber, i, j, s;
+		for(i = lb; i; r && s.unshift(r), x.set(x.add(new BigNumber(s.join("")))))
+			for(s = (new Array(lb - --i)).join("0").split(""), r = 0, j = la; j; r += a[--j] * b[i], s.unshift(r % 10), r = (r / 10) >>> 0);
+		return o._s = o._s != n._s, o._f = ((r = la + lb - o._f - n._f) >= (j = (o._d = x._d).length) ? this._zeroes(o._d, r - j + 1, 1).length : j) - r, o.round();
+	};
+	o.divide = function(n){
+		if((n = new BigNumber(n)) == "0")
+			throw new Error("Division by 0");
+		else if(this == "0")
+			return new BigNumber;
+		var o = new BigNumber(this), a = o._d, b = n._d, la = a.length - o._f,
+		lb = b.length - n._f, r = new BigNumber, i = 0, j, s, l, f = 1, c = 0, e = 0;
+		r._s = o._s != n._s, r.precision = Math.max(o.precision, n.precision),
+		r._f = +r._d.pop(), la != lb && o._zeroes(la > lb ? b : a, Math.abs(la - lb));
+		n._f = b.length, b = n, b._s = false, b = b.round();
+		for(n = new BigNumber; a[0] == "0"; a.shift());
+		out:
+		do{
+			for(l = c = 0, n == "0" && (n._d = [], n._f = 0); i < a.length && n.compare(b) == -1; ++i){
+				(l = i + 1 == a.length, (!f && ++c > 1 || (e = l && n == "0" && a[i] == "0")))
+				&& (r._f == r._d.length && ++r._f, r._d.push(0));
+				(a[i] == "0" && n == "0") || (n._d.push(a[i]), ++n._f);
+				if(e)
+					break out;
+				if((l && n.compare(b) == -1 && (r._f == r._d.length && ++r._f, 1)) || (l = 0))
+					while(r._d.push(0), n._d.push(0), ++n._f, n.compare(b) == -1);
+			}
+			if(f = 0, n.compare(b) == -1 && !(l = 0))
+				while(l ? r._d.push(0) : l = 1, n._d.push(0), ++n._f, n.compare(b) == -1);
+			for(s = new BigNumber, j = 0; n.compare(y = s.add(b)) + 1 && ++j; s.set(y));
+			n.set(n.subtract(s)), !l && r._f == r._d.length && ++r._f, r._d.push(j);
+		}
+		while((i < a.length || n != "0") && (r._d.length - r._f) <= r.precision);
+		return r.round();
+	};
+	o.mod = function(n){
+		return this.subtract(this.divide(n).intPart().multiply(n));
+	};
+	o.pow = function(n){
+		var o = new BigNumber(this), i;
+		if((n = (new BigNumber(n)).intPart()) == 0) return o.set(1);
+		for(i = Math.abs(n); --i; o.set(o.multiply(this)));
+		return n < 0 ? o.set((new BigNumber(1)).divide(o)) : o;
+	};
+	o.set = function(n){
+		return this.constructor(n), this;
+	};
+	o.compare = function(n){
+		var a = this, la = this._f, b = new BigNumber(n), lb = b._f, r = [-1, 1], i, l;
+		if(a._s != b._s)
+			return a._s ? -1 : 1;
+		if(la != lb)
+			return r[(la > lb) ^ a._s];
+		for(la = (a = a._d).length, lb = (b = b._d).length, i = -1, l = Math.min(la, lb); ++i < l;)
+			if(a[i] != b[i])
+				return r[(a[i] > b[i]) ^ a._s];
+		return la != lb ? r[(la > lb) ^ a._s] : 0;
+	};
+	o.negate = function(){
+		var n = new BigNumber(this); return n._s ^= 1, n;
+	};
+	o.abs = function(){
+		var n = new BigNumber(this); return n._s = 0, n;
+	};
+	o.intPart = function(){
+		return new BigNumber((this._s ? "-" : "") + (this._d.slice(0, this._f).join("") || "0"));
+	};
+	o.valueOf = o.toString = function(){
+		var o = this;
+		return (o._s ? "-" : "") + (o._d.slice(0, o._f).join("") || "0") + (o._f != o._d.length ? "." + o._d.slice(o._f).join("") : "");
+	};
+	o._zeroes = function(n, l, t){
+		var s = ["push", "unshift"][t || 0];
+		for(++l; --l;  n[s](0));
+		return n;
+	};
+	o.round = function(){
+		if("_rounding" in this) return this;
+		var $ = BigNumber, r = this.roundType, b = this._d, d, p, n, x;
+		for(this._rounding = true; this._f > 1 && !b[0]; --this._f, b.shift());
+		for(d = this._f, p = this.precision + d, n = b[p]; b.length > d && !b[b.length -1]; b.pop());
+		x = (this._s ? "-" : "") + (p - d ? "0." + this._zeroes([], p - d - 1).join("") : "") + 1;
+		if(b.length > p){
+			n && (r == $.DOWN ? false : r == $.UP ? true : r == $.CEIL ? !this._s
+			: r == $.FLOOR ? this._s : r == $.HALF_UP ? n >= 5 : r == $.HALF_DOWN ? n > 5
+			: r == $.HALF_EVEN ? n >= 5 && b[p - 1] & 1 : false) && this.add(x);
+			b.splice(p, b.length - p);
+		}
+		return delete this._rounding, this;
+	};
+}