Flutter Dart BigDecimal

目录

  • 前言
  • API
    • 构造函数
    • 四则及幂运算
    • 其他
  • 代码
    • BigDecimal.dart
    • bigdecimal_test.dart

前言

Dart中只有BigInt没有BigDecimal,所以需要手动去实现BigDecimal。
如果我的代码帮到你,请给我点个赞。

API

构造函数

  • BigDecimal([dynamic number]) 将任意toString后能表示为小数的类型转换为BigDecimal
  • BigDecimal.fromReal(List real) 将BigDecimal实数部分转换为BigDecimal
  • BigDecimal.fromDecimal(List decimal) 将BigDecimal小数部分转换为BigDecimal

四则及幂运算

  • BigDecimal operator + (dynamic number)
  • BigDecimal operator - (dynamic number)
  • BigDecimal operator * (dynamic number)
  • BigDecimal operator / (dynamic number)
  • BigDecimal pow(int n) 快速幂运算

其他

  • BigDecimal disablePrecisionLimit() 取消除法运算精度,可能导致程序无限循环进行除法运算
  • BigDecimal setDivMaxPrecision(int precision) 设置除法运算最大的精度,默认1000
  • BigDecimal clone() 克隆BigDecimal对象
  • BigDecimal abs() 取正
  • List real() 获取实数部分
  • List decimal() 获取小数部分

代码

BigDecimal.dart

import 'dart:math' as Math;//TODO StringBuilder自己想办法解决
import 'package:module_utils/tools/StringBuilder.dart';///高精度大数
///
/// eg: [123][1][2][3].[123][1][123] => 123 000000001 000000002 000000003.000000123 000000001 000000123
class BigDecimal{static get nan  => BigDecimal("nan");static get zero => BigDecimal("0.0");static get one  => BigDecimal("1.0");static get two  => BigDecimal("2.0");//实数部分 非空 [高位,低位] 值∈[0, 1E9-1]final List<int> _real = [];//小数部分 非空 [高位,低位] 值∈[0, 1E9-1]final List<int> _decimal = [];//正负号 true:+ false:-bool _sign = true;//无穷大 除数为0时,商为无穷大bool _nan  = false;//sqrt(int.max = 9223372036854775807) = 3037000499//每个list元素最大的值 1E10 - 1static const int _MaxUnit = 999999999;static const int _1E9    = 1000000000;static BigDecimal min(BigDecimal b1, BigDecimal b2){return b1<b2 ? b1 : b2;}static BigDecimal max(BigDecimal b1, BigDecimal b2){return b1<b2 ? b2 : b1;}static int _lengthOfNormal([int num]) => 9;//求实数最高元素的位数长度 eg: 123456 => 6static int _lengthOfReal(int num){return _splitReal(num).length;}//求小数最低元素的位数长度 eg: 1234560 = 00123456 => 8static int _lengthOfDecimal(int num){return _splitDecimal(num).length;}//将整数拆分 eg: 123456 => [0,0,0,1,2,3,4,5,6]static List<int> _splitNormal(int num){return List.filled(9, 1).asMap().keys.map((e) => num~/Math.pow(10,e)%10).toList().reversed.toList();}//将实数高位元素拆分 eg: 123456 => [1,2,3,4,5,6]static List<int> _splitReal(int num){return List.filled(9, 1).asMap().keys.map((e) => num~/Math.pow(10,e)%10).toList().reversed.skipWhile((value) => value==0).toList();}//将小数低位元素拆分 eg: 123456000 => [1,2,3,4,5,6] err:0000100000static List<int> _splitDecimal(int num){return num == 0 ? [0] :List.filled(9, 1).asMap().keys.map((e) => num~/Math.pow(10,e)%10).toList().skipWhile((value) => value==0).toList().reversed.toList();}//将整数数组拆分 eg: [123,456,789] => [0,0,0,0,0,0,1,2,3,0,0,0,0,0,0,4,5,6,0,0,0,0,0,0,7,8,9]static List<int> __splitNormal(List<int> numbers){return numbers.map((e) => _splitNormal(e)).expand((e) => e).toList();}//将实数元素数组拆分 eg: [123,456,7890] => [1,2,3,0,0,0,0,0,0,4,5,6,0,0,0,0,0,7,8,9,0]static List<int> __splitReal(List<int> numbers){return __splitNormal(numbers).skipWhile((value) => value==0).toList();}//将小数元素数组拆分 eg: [123,456,7890] => [0,0,0,0,0,0,1,2,3,0,0,0,0,0,0,4,5,6,0,0,0,0,0,7,8,9]static List<int> __splitDecimal(List<int> numbers){var result = __splitNormal(numbers);for(int i=result.length-1; i>0; --i){if(result[i] == 0) result.removeLast();else break;}return result;}//将按位分割的整数数组组合成一个整数 eg: [1,2,3,4,5,6] => 123456static int _combineNormal(List<int> numbers){return int.parse(numbers.join());}//将按位分割的整数数组组合成一个实数高位元素 eg: [0,1,2,3,4,5,6] => 123456static int _combineReal(List<int> numbers){return int.parse(numbers.skipWhile((e) => e==0).join().padLeft(1,"0"));}//将按位分割的整数数组组合成一个小数低位元素 eg: [1,2,3,4,5,6] => 123456000static int _combineDecimal(List<int> numbers){return numbers.length==1&&numbers[0]==0 ? 0 : int.parse(numbers.join().padRight(9,"0"));}//将按位分割的整数数组组组合成大数实数元素数组 eg: [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7] => [12345678,901234567]static List<int> __combineReal(List<int> numbers){List<int> nums = numbers.skipWhile((e) => e==0).toList();return List.filled(nums.length~/10 + (nums.length%10==0?0:1), 0).asMap().keys.map((e) => _combineReal(nums.sublist(Math.max(0,nums.length-(10*(e+1))), nums.length-(10*e)))).toList();}//将按位分割的整数数组组组合成大数小数元素数组 eg: [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7] => [123456789,12345670]static List<int> __combineDecimal(List<int> numbers){var nums = []..addAll(numbers);while(nums.length%10 != 0) nums.add(0);return List.filled(nums.length~/10 + (nums.length%10==0?0:1), 0).asMap().keys.map((e) =>e==(nums.length~/10-1)? _combineDecimal(nums.sublist(10*e, Math.min(10*(e+1), nums.length))): _combineReal   (nums.sublist(10*e, 10*(e+1)))).toList();}static List<int> _parseReal(String part){List<int> result = [];while(part.length>0){int length = part.length;int index  = Math.max(length-9, 0);int num    = int.parse(part.substring(index, part.length));part   = part.substring(0, index);result.insert(0,num);}if(result.isEmpty) result.add(0);return result;}static List<int> _parseDecimal(String part){List<int> result = [];while(part.length>0){int length = part.length;int index  = Math.min(length, 9);int num    = int.parse(part.substring(0,index).padRight(9,"0"));part   = part.substring(index);result.add(num);}if(result.isEmpty) result.add(0);return result;}BigDecimal.fromReal(List<int> real){_real   .addAll(real);_decimal.add(0);}BigDecimal.fromDecimal(List<int> decimal){_real   .add(0);_decimal.addAll(decimal);}BigDecimal([dynamic number]){try{if(number == null) return;if(number is BigDecimal){_real.addAll(number._real);_decimal.addAll(number._decimal);_sign = number._sign;_nan  = number._nan;return;}if(number is double){if(number.isNaN){_nan  = true;return;}BigDecimal decimal = BigDecimal(number.toString());_real.addAll(decimal._real);_decimal.addAll(decimal._decimal);_sign = decimal._sign;_nan  = decimal._nan;return;}if(number is int) {_sign = number>-1;_real.add(number.abs());_nan  = number.isNaN;return;}String strNumber = number.toString().trim();if(strNumber.toLowerCase() == "nan"){_sign = true;_nan  = true;return;}_nan = false;String num = "";//判断正负号for(int i=0,ni=strNumber.length; i<ni; ++i){if(strNumber.codeUnitAt(i)=='-'.codeUnitAt(0)){_sign = false;break;}if(strNumber.codeUnitAt(i)=='.'.codeUnitAt(0)){_sign = true;break;}if(strNumber.codeUnitAt(i)>='0'.codeUnitAt(0) && strNumber.codeUnitAt(i)<='9'.codeUnitAt(0)){_sign = true;break;}}//格式化for(int i=0,ni=strNumber.length; i<ni; ++i){if(strNumber.codeUnitAt(i)>='0'.codeUnitAt(0) && strNumber.codeUnitAt(i)<='9'.codeUnitAt(0)){num += strNumber.substring(i,i+1);}if(strNumber.codeUnitAt(i)=='.'.codeUnitAt(0) && num.indexOf(".")<0){num += strNumber.substring(i,i+1);}}if(num.length == 0) num = "0.0";else if(num.indexOf(".")<0) num = num+".0";int index = num.indexOf(".");String strR = num.substring(0, index);String strD = num.substring(index+1);_real   .addAll(_parseReal   (strR));_decimal.addAll(_parseDecimal(strD));}finally{if(_real   .isEmpty) _real   .add(0);if(_decimal.isEmpty) _decimal.add(0);}}int compare(BigDecimal another){if(_nan && !another._nan) return  1;if(!_nan && another._nan) return -1;if(_sign && !another._sign) return  1;if(!_sign && another._sign) return -1;bool sign = _sign;//判断实数部分if(_real.length > another._real.length) return sign ?  1 : -1;if(_real.length < another._real.length) return sign ? -1 :  1;for(int i=0,ni=_real.length; i<ni; ++i){if(_real[i]>another._real[i]) return sign ?  1 : -1;if(_real[i]<another._real[i]) return sign ? -1 :  1;}//以下实数部分相等//判断小数部分//判断高位for(int i=0, ni=Math.min(_decimal.length, another._decimal.length)-1; i<ni;++i){if(_decimal[i]>another._decimal[i]) return sign ?  1 : -1;if(_decimal[i]<another._decimal[i]) return sign ? -1 :  1;}//将整数各个位分割以便判断低位int index = Math.min(_decimal.length, another._decimal.length)-1;List<int> num1 = List.filled(10, 1).asMap().keys.map((e) =>         _decimal[index]~/Math.pow(10,e)%10).toList().reversed.toList();List<int> num2 = List.filled(10, 1).asMap().keys.map((e) => another._decimal[index]~/Math.pow(10,e)%10).toList().reversed.toList();for(int i=0,ni=Math.min(num1.length, num2.length); i<ni;++i){if(num1[i]>num2[i]) return sign ?  1 : -1;if(num1[i]<num2[i]) return sign ? -1 :  1;}if(num1.length>num2.length) return sign ?  1 : -1;if(num2.length<num2.length) return sign ? -1 :  1;if(_decimal.length > another._decimal.length) return sign ?  1 : -1;if(_decimal.length < another._decimal.length) return sign ? -1 :  1;return 0;}bool operator <  (dynamic number) => this.compare(BigDecimal(number)) == -1;bool operator >  (dynamic number) => this.compare(BigDecimal(number)) ==  1;bool operator == (dynamic number) => this.compare(BigDecimal(number)) ==  0;BigDecimal operator + (dynamic number){BigDecimal another = BigDecimal(number);if(_nan | another._nan) return nan;//符号不一致if(_sign ^ another._sign){//当做减法处理if(_sign) return this - another.abs();return another - abs();}//符号一致处理//region 小数部分List<int> dec1 = _decimal;List<int> dec2 = another._decimal;int decLen1 = dec1.length;int decLen2 = dec2.length;//  计算小数公共元素的长度int decCommonLen = Math.min(decLen1, decLen2);//  小数计算结果存放List<int> decSum = []..addAll(dec1.sublist(decCommonLen))..addAll(dec2.sublist(decCommonLen));//  进位标记bool carry = false;//  小数公共元素数组求和for(int i=decCommonLen-1; i>-1; --i){int sum =  dec1[i] + dec2[i] + (carry?1:0);carry = sum >= _1E9;if(carry) sum = sum%_1E9;decSum.insert(0, sum);}// 小数格式化for(int i=decSum.length-1; i>0; --i){if(decSum[i]==0) decSum.removeLast();else break;}//endregion//region 实数部分List<int> real1 =         _real;List<int> real2 = another._real;int realLen1 = real1.length;int realLen2 = real2.length;List<int> realSum = [];//  公共部分求和for(int i=realLen1-1, j=realLen2-1; j>-1||i>-1; --i,--j){int sum =(i<0?0:real1[i]) + (j<0?0:real2[j]) + (carry?1:0);carry = sum >= _1E9;if(carry) sum = sum%_1E9;realSum.insert(0, sum);}if(carry) realSum.insert(0, 1);//endregionreturn BigDecimal().._nan = false.._sign = _sign.._real.clear().._real.addAll(realSum).._decimal.clear().._decimal.addAll(decSum);}BigDecimal operator - (dynamic number){BigDecimal another = BigDecimal(number);if(_nan | another._nan) return nan;//符号不一致if(_sign ^ another._sign){//当做加法处理if(_sign) return this + another.abs();return (abs() + another.abs()).._sign = false;}//符号一致且都是正数if(_sign){//减不过就换位减if(this < another){return (another - this).._sign = false;}}//符号一致且都是负数else{//-a - -b  =>  b - areturn another.abs() - abs();}bool borrow = false;//region 小数部分List<int> dec1 =         _decimal;List<int> dec2 = another._decimal;int decLen1 = dec1.length;int decLen2 = dec2.length;List<int> decSub = [];//  求差for(int i=Math.max(decLen1,decLen2)-1; i>-1; --i){int num1 = i < decLen1 ? dec1[i] : 0;int num2 = i < decLen2 ? dec2[i] : 0;int sub = num1 - num2 - (borrow?1:0);borrow = sub<0;if(borrow) sub += _1E9;decSub.insert(0, sub);}// 小数格式化for(int i=decSub.length-1; i>0; --i){if(decSub[i]==0) decSub.removeLast();else break;}//endregion//region 实数部分List<int> real1 =         _real;List<int> real2 = another._real;int realLen1 = real1.length;int realLen2 = real2.length;List<int> realSub = [];//  求差for(int idx1=realLen1-1, idx2=realLen2-1, i=Math.max(realLen1, realLen2); i>0; --i,--idx1,--idx2){int sub = (idx1<0?0:real1[idx1]) - (idx2<0?0:real2[idx2]) - (borrow?1:0);borrow = sub<0;if(borrow) sub += _1E9;realSub.insert(0, sub);}// 实数格式化for(int i=0, ni=realSub.length-1; i<ni; ++i){if(realSub[0]==0) realSub.removeAt(0);else break;}//endregionreturn BigDecimal().._nan = false.._sign = !borrow.._real.clear().._real.addAll(realSub).._decimal.clear().._decimal.addAll(decSub);}BigDecimal operator * (dynamic number){BigDecimal another = BigDecimal(number);if(_nan | another._nan) return nan;if(this == zero || another == zero) return zero;if(this == one) return another;if(another == one) return this.clone();//将两个数拆分成位数组List<int> dec1 =         _decimal;List<int> dec2 = another._decimal;int decLen1 = dec1.length;int decLen2 = dec2.length;int decMulLen = decLen1 + decLen2;List<int> real1 =         _real;List<int> real2 = another._real;List<int> num1 = []..addAll(real1)..addAll(dec1);List<int> num2 = []..addAll(real2)..addAll(dec2);int numLen1 = num1.length;int numLen2 = num2.length;int numMulLen = numLen1 + numLen2;//可能的最大长度//计算结果List<int> numMul = List.filled(numMulLen+1, 0);Function(int, int) add = (int index, int number){numMul[index] += number;int carry = numMul[index]~/_1E9;while(carry>0){numMul[index] %= _1E9;numMul[--index] += carry;carry = numMul[index]~/_1E9;}};for(int i=numLen2-1, idx2=0, idx3=numMulLen; i>-1; --i,++idx2,idx3=numMulLen-idx2){for(int j=numLen1-1, idx1=numMulLen-1-idx2; j>-1; --j,--idx1,--idx3){int mul = num2[i]*num1[j];add(idx3, mul);}}List<int> real    = numMul.sublist(0                          , numMul.length - decMulLen);List<int> decimal = numMul.sublist(numMul.length - decMulLen);while(real.length>1){if(real[0]==0) real.removeAt(0);else break;}// 小数格式化for(int i=decimal.length-1; i>0; --i){if(decimal[i]==0) decimal.removeLast();else break;}return BigDecimal().._sign = !(_sign ^ another._sign).._nan = false.._real.clear().._real.addAll(real).._decimal.clear().._decimal.addAll(decimal);}BigDecimal operator / (dynamic number){BigDecimal another = BigDecimal(number);if(_nan | another._nan) return nan;if(this == zero) return zero;if(another == zero) return nan;//将两个数拆分成元素数组List<int> dec1 =         _decimal;List<int> dec2 = another._decimal;List<int> real1 =         _real;List<int> real2 = another._real;List<int> num1 = []..addAll(real1)..addAll(dec1);List<int> num2 = []..addAll(real2)..addAll(dec2);//初始化除数的倍数final Map<int, BigDecimal> mTimes = {0:BigDecimal.zero, 1:BigDecimal.fromReal(num2)};Function(BigDecimal, BigDecimal) add = (num1,num2) => BigDecimal.fromReal((num1+num2)._real);Function(int) timesOfDivisor;timesOfDivisor = (time){BigDecimal value = mTimes[time];if(value != null) return value;value = add(timesOfDivisor(time~/2 + (time%2==0?0:1)), timesOfDivisor(time~/2));mTimes[time] = value;return value;};//region 二分减法//b1~/b2 => [quotient, remainder]Function(BigDecimal, BigDecimal) binSub = (BigDecimal b1, BigDecimal b2){//平均计算 log2(10)≈3   log2(1E9)≈30//                    0 9 => 5//       0 4 => 2                  6 9 => 7//0 2 => 1     3 4 => 3      6 7 => 6    8 9 => 8// 0 1 2          3 4     5     6 7        8 9int l = 0, r = _MaxUnit;while(l<r){int m = (l+r)~/2;BigDecimal b3 = timesOfDivisor(m);int comp = b1.compare(b3);if(comp == 0) return [m,[0]];//b1 > b3 m可能是结果if(comp == 1){if(l+1 == r){BigDecimal b4 = timesOfDivisor(r);comp = b1.compare(b4);if(comp == 0) return [r,[0]];if(comp == 1) return [r,(b1-b4)._real];return [l,(b1-b3)._real];}l = m;continue;}//b1 < b3 m一定不是结果if(l+1 == r) return [m,(b1-b3)._real];r = m - 1;}//一定不会执行此语句return [l,(b1-timesOfDivisor(l))._real];};//endregion//求商List<int> numDiv = [];int nRealPrecision = real1.length+dec2.length;int pPrecision = -nRealPrecision;List<int>  dividend = [];List<int>  divisor = num2;BigDecimal bdDivisor  = BigDecimal.fromReal(num2);int divMaxBitPrecision = _divMaxPrecision<0?-1:_divMaxPrecision~/9 + (_divMaxPrecision%9==0?0:1);for(int i=0; i<num1.length||dividend.isNotEmpty; ++i){if(divMaxBitPrecision>-1){if(pPrecision>=divMaxBitPrecision) break;}// print("#${i.toString().padLeft(4,"0")}: [${dividend.length}]:$dividend");++pPrecision;int num = i<num1.length?num1[i]:0;if(num!=0 || dividend.isNotEmpty) dividend.add(num);//不够减if(dividend.length<divisor.length) {numDiv.add(0);continue;}BigDecimal bdDividend = BigDecimal.fromReal(dividend);List       result     = binSub(bdDividend, bdDivisor);int        quotient   = result[0];List<int>  remainder  = result[1];numDiv.add(quotient);if(quotient == 0) continue;dividend.clear();dividend.addAll(remainder.skipWhile((e) => e==0).toList());}List<int> divReal    = numDiv.sublist(0             , nRealPrecision).skipWhile((e) => e==0).toList();List<int> divDecimal = numDiv.sublist(nRealPrecision);if(divReal   .isEmpty) divReal   .add(0);if(divDecimal.isEmpty) divDecimal.add(0);//精度对齐if(_divMaxPrecision>-1&&_divMaxPrecision%9!=0){int last = divDecimal.last;int len  = _divMaxPrecision%9;List<int> llast = _splitDecimal(last);llast = llast.sublist(0, Math.min(llast.length, len));divDecimal.removeLast();divDecimal.add(_combineDecimal(llast));}for(int i=divDecimal.length-1; i>0; --i){if(divDecimal[i]==0) divDecimal.removeLast();else break;}return BigDecimal().._sign = !(_sign ^ another._sign).._nan = false.._real.clear().._real.addAll(divReal).._decimal.clear().._decimal.addAll(divDecimal);}//为了防止计算除法时出现无限小数,设置此位防止死循环//负数代表不限制int _divMaxPrecision = 1000;BigDecimal setDivMaxPrecision(int precision){_divMaxPrecision = precision;return this;}BigDecimal disablePrecisionLimit(){_divMaxPrecision = -1;return this;}List<int> real   () => __splitReal   (_real   );List<int> decimal() => __splitDecimal(_decimal);BigDecimal _powInternal(int n, Map<int,BigDecimal> mPow){BigDecimal bd = mPow[n];if(bd!=null) return bd;int p1 = n~/2;int p2 = p1 + (n%2==0?0:1);BigDecimal bdPow = _powInternal(p1, mPow)*_powInternal(p2, mPow);mPow[n] = bdPow;return bdPow.clone();}BigDecimal pow(int n){return _powInternal(n, {0:BigDecimal.one,1:clone()});}BigDecimal clone() => BigDecimal().._nan = false.._sign = _sign.._real.clear().._real.addAll(_real).._decimal.clear().._decimal.addAll(_decimal);BigDecimal abs(){return BigDecimal().._sign = true.._nan = _nan.._real.clear().._real.addAll(_real).._decimal.clear().._decimal.addAll(_decimal);}String toString(){if(_nan) return "nan";StringBuilder sb = StringBuilder();if(!_sign) sb.append("-");sb.append(_real[0].toString());for(int i=1,ni=_real.length;i<ni;++i){sb.append(_real[i].toString().padLeft(9,'0'));}sb.append(".");if(_decimal.length>1) {for(int i=0,ni=_decimal.length-1;i<ni;++i){sb.append(_decimal[i].toString().padLeft(9,'0'));}}sb.append(_splitDecimal(_decimal[_decimal.length-1]).join());return sb.toString();}int get hashCode => _real.hashCode * _decimal.hashCode;
}

bigdecimal_test.dart

import 'dart:math';import 'package:flutter_test/flutter_test.dart';import 'BigDecimal.dart';
import 'StringBuilder.dart';//region randomGenerate
Random random = Random(DateTime.now().millisecondsSinceEpoch);
String generateNumber({bool decimal=false, int length=0, int maxLength=10000}){while(length==0) length = random.nextInt(maxLength+1);StringBuilder sb = StringBuilder();while(sb.length() < length){int num = random.nextInt(min(0x7fffffff,pow(10,min(10,length-sb.length()))));sb.append(num.toString());}if(decimal){if(sb.charAt(sb.length()-1) == "0".codeUnitAt(0)){int num = random.nextInt(10);while(num==0) num = random.nextInt(10);sb.replace(sb.length()-1, sb.length(), num.toString());}}else{if(sb.charAt(0) == "0".codeUnitAt(0)){int num = random.nextInt(10);while(num==0) num = random.nextInt(10);sb.replace(0, 1, num.toString());}}return sb.toString();
}
//endregionvoid main(){test("BigDecimal constructor test", ()async{//验证nanprint("Testing NAN");expect(BigDecimal("nan").toString()=="nan" , isTrue);//验证1,1E10,1E100,1E1000,1E10000print("Testing Positive");expect(BigDecimal("1".padRight(pow(10, 0)+1,"0")).toString(), "1".padRight(pow(10, 0)+1,"0")+".0");expect(BigDecimal("1".padRight(pow(10, 1)+1,"0")).toString(), "1".padRight(pow(10, 1)+1,"0")+".0");expect(BigDecimal("1".padRight(pow(10, 2)+1,"0")).toString(), "1".padRight(pow(10, 2)+1,"0")+".0");expect(BigDecimal("1".padRight(pow(10, 3)+1,"0")).toString(), "1".padRight(pow(10, 3)+1,"0")+".0");expect(BigDecimal("1".padRight(pow(10, 4)+1,"0")).toString(), "1".padRight(pow(10, 4)+1,"0")+".0");//验证1E-1,1E-10,1E-100,1E-1000,1E-10000print("Testing Negative");expect(BigDecimal("0.${"1".padLeft(pow(10, 0),"0")}").toString(), "0.${"1".padLeft(pow(10, 0),"0")}");expect(BigDecimal("0.${"1".padLeft(pow(10, 1),"0")}").toString(), "0.${"1".padLeft(pow(10, 1),"0")}");expect(BigDecimal("0.${"1".padLeft(pow(10, 2),"0")}").toString(), "0.${"1".padLeft(pow(10, 2),"0")}");expect(BigDecimal("0.${"1".padLeft(pow(10, 3),"0")}").toString(), "0.${"1".padLeft(pow(10, 3),"0")}");expect(BigDecimal("0.${"1".padLeft(pow(10, 4),"0")}").toString(), "0.${"1".padLeft(pow(10, 4),"0")}");//随机测验实数和小数长度[1,10000]print("Testing Random");for(int i=0;i<10000;++i){bool   sign    = random.nextBool();String real    = generateNumber(decimal: false);String decimal = generateNumber(decimal: true );String number  = "${sign?"":"-"}$real.$decimal";print("\tEvaluating #${i.toString().padLeft(4)} ${sign?" ":"-"}[${real.length.toString().padLeft(5)}].[${decimal.length.toString().padLeft(5)}]:$number");expect(BigDecimal(number).toString(), number, reason: "Compare error $i: ${sign?" ":""}$number");}print("Test passed!!!");},timeout: Timeout(Duration(minutes: 1)));test("BigDecimal compare test", ()async{expect(BigDecimal("-1").compare(BigDecimal("1" )), -1);expect(BigDecimal("1" ).compare(BigDecimal("-1")),  1);expect(BigDecimal("1" ).compare(BigDecimal("1" )),  0);//Test 99...9 10....0expect(BigDecimal("9".padLeft (10   ,"9")).compare(BigDecimal("1".padRight(11   ,"0"))), -1);expect(BigDecimal("1".padRight(11   ,"0")).compare(BigDecimal("9".padLeft (10   ,"9"))),  1);expect(BigDecimal("9".padLeft (100  ,"9")).compare(BigDecimal("1".padRight(101  ,"0"))), -1);expect(BigDecimal("1".padRight(101  ,"0")).compare(BigDecimal("9".padLeft (100  ,"9"))),  1);expect(BigDecimal("9".padLeft (1000 ,"9")).compare(BigDecimal("1".padRight(1001 ,"0"))), -1);expect(BigDecimal("1".padRight(1001 ,"0")).compare(BigDecimal("9".padLeft (1000 ,"9"))),  1);expect(BigDecimal("9".padLeft (10000,"9")).compare(BigDecimal("1".padRight(10001,"0"))), -1);expect(BigDecimal("1".padRight(10001,"0")).compare(BigDecimal("9".padLeft (10000,"9"))),  1);//Test -99...9 -10....0expect(BigDecimal("-${"9".padLeft (10   ,"9")}").compare(BigDecimal("-${"1".padRight(11   ,"0")}")),  1);expect(BigDecimal("-${"1".padRight(11   ,"0")}").compare(BigDecimal("-${"9".padLeft (10   ,"9")}")), -1);expect(BigDecimal("-${"9".padLeft (100  ,"9")}").compare(BigDecimal("-${"1".padRight(101  ,"0")}")),  1);expect(BigDecimal("-${"1".padRight(101  ,"0")}").compare(BigDecimal("-${"9".padLeft (100  ,"9")}")), -1);expect(BigDecimal("-${"9".padLeft (1000 ,"9")}").compare(BigDecimal("-${"1".padRight(1001 ,"0")}")),  1);expect(BigDecimal("-${"1".padRight(1001 ,"0")}").compare(BigDecimal("-${"9".padLeft (1000 ,"9")}")), -1);expect(BigDecimal("-${"9".padLeft (10000,"9")}").compare(BigDecimal("-${"1".padRight(10001,"0")}")),  1);expect(BigDecimal("-${"1".padRight(10001,"0")}").compare(BigDecimal("-${"9".padLeft (10000,"9")}")), -1);//Test randomfor(int i=0; i<10000; ++i){bool   sign1       = random.nextBool();String strReal1    = generateNumber(decimal: false);String strDecimal1 = generateNumber(decimal: true );String number1     = "${sign1?"":"-"}$strReal1.$strDecimal1";bool   sign2       = random.nextBool();String strReal2    = generateNumber(decimal: false);String strDecimal2 = generateNumber(decimal: true );String number2     = "${sign2?"":"-"}$strReal2.$strDecimal2";int compare;if( sign1 && !sign2) compare =  1;if(!sign1 &&  sign2) compare = -1;if(sign1 == sign2){bool sign = sign1;if     (strReal1.length>strReal2.length) compare =  1;else if(strReal1.length<strReal2.length) compare = -1;else compare = strReal1.compareTo(strReal2);if(compare==0){String strDecimal3 = strDecimal1.padRight(max(strDecimal1.length, strDecimal2.length),"0");String strDecimal4 = strDecimal2.padRight(max(strDecimal1.length, strDecimal2.length),"0");compare = strDecimal3.compareTo(strDecimal4);}if(compare!=0){compare = sign ? compare : -compare;}}expect(BigDecimal(number1).compare(BigDecimal(number2)), compare);}});test("BigDecimal operator + test", ()async{print("Testing Basic");expect((BigDecimal("1" )+BigDecimal("1" )).toString(), BigDecimal("2" ).toString());expect((BigDecimal("-1")+BigDecimal("1" )).toString(), BigDecimal.zero .toString());expect((BigDecimal("-1")+BigDecimal("-1")).toString(), BigDecimal("-2").toString());print("Testing Real");expect((BigDecimal("9".padLeft (10   ,"9"))+BigDecimal.one).toString(), BigDecimal("1".padRight(11   ,"0")).toString());expect((BigDecimal("9".padLeft (100  ,"9"))+BigDecimal.one).toString(), BigDecimal("1".padRight(101  ,"0")).toString());expect((BigDecimal("9".padLeft (1000 ,"9"))+BigDecimal.one).toString(), BigDecimal("1".padRight(1001 ,"0")).toString());expect((BigDecimal("9".padLeft (10000,"9"))+BigDecimal.one).toString(), BigDecimal("1".padRight(10001,"0")).toString());print("Testing Decimal");expect((BigDecimal("0.${"1".padLeft(pow(10, 0),"0")}")+BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}")).toString(), BigDecimal.one.toString());expect((BigDecimal("0.${"1".padLeft(pow(10, 1),"0")}")+BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}")).toString(), BigDecimal.one.toString());expect((BigDecimal("0.${"1".padLeft(pow(10, 2),"0")}")+BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}")).toString(), BigDecimal.one.toString());expect((BigDecimal("0.${"1".padLeft(pow(10, 3),"0")}")+BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}")).toString(), BigDecimal.one.toString());expect((BigDecimal("0.${"1".padLeft(pow(10, 4),"0")}")+BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}")).toString(), BigDecimal.one.toString());print("Testing random");for(int i=0; i<10000; ++i) {print("\tEvaluating #${i.toString().padLeft(4)} ->");String strReal1 = generateNumber(decimal: false);String strDecimal1 = generateNumber(decimal: true);String number1 = "$strReal1.$strDecimal1";String strReal2 = generateNumber(decimal: false);String strDecimal2 = generateNumber(decimal: true);String number2 = "$strReal2.$strDecimal2";print("\t\t[${strReal1.length.toString().padLeft(5)}].[${strDecimal1.length.toString().padLeft(5)}]:${strReal1.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal1");print("\t\t[${strReal2.length.toString().padLeft(5)}].[${strDecimal2.length.toString().padLeft(5)}]:${strReal2.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal2");BigInt biReal1    = BigInt.parse(strReal1   );BigInt biDecimal1 = BigInt.parse(strDecimal1.padRight(max(strDecimal1.length, strDecimal2.length),"0"));BigInt biReal2    = BigInt.parse(strReal2   );BigInt biDecimal2 = BigInt.parse(strDecimal2.padRight(max(strDecimal1.length, strDecimal2.length),"0"));BigInt biDecimal3 = biDecimal1 + biDecimal2;String strDecimal3 = biDecimal3.toString();bool   carry       = max(strDecimal1.length, strDecimal2.length) != strDecimal3.length;BigInt biReal3     = biReal1    + biReal2 + (carry?BigInt.one : BigInt.zero);String strReal3    = biReal3.toString();if(carry) strDecimal3 = strDecimal3.substring(1);expect(BigDecimal(number1)+BigDecimal(number2), BigDecimal("$strReal3.$strDecimal3"));}});test("BigDecimal operator - test",()async{print("Testing Basic");expect((BigDecimal("1" )-BigDecimal("1" )).toString(), BigDecimal.zero .toString());expect((BigDecimal("2" )-BigDecimal("1" )).toString(), BigDecimal.one  .toString());expect((BigDecimal.zero -BigDecimal("1" )).toString(), BigDecimal("-1").toString());print("Testing Real");expect((BigDecimal("1".padRight(11   ,"0"))-BigDecimal.one).toString(), BigDecimal("9".padLeft (10   ,"9")).toString());expect((BigDecimal("1".padRight(101  ,"0"))-BigDecimal.one).toString(), BigDecimal("9".padLeft (100  ,"9")).toString());expect((BigDecimal("1".padRight(1001 ,"0"))-BigDecimal.one).toString(), BigDecimal("9".padLeft (1000 ,"9")).toString());expect((BigDecimal("1".padRight(10001,"0"))-BigDecimal.one).toString(), BigDecimal("9".padLeft (10000,"9")).toString());print("Testing Decimal");expect((BigDecimal.one-BigDecimal("0.${"1".padLeft(pow(10, 0),"0")}")).toString(), BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").toString());expect((BigDecimal.one-BigDecimal("0.${"1".padLeft(pow(10, 1),"0")}")).toString(), BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").toString());expect((BigDecimal.one-BigDecimal("0.${"1".padLeft(pow(10, 2),"0")}")).toString(), BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").toString());expect((BigDecimal.one-BigDecimal("0.${"1".padLeft(pow(10, 3),"0")}")).toString(), BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").toString());expect((BigDecimal.one-BigDecimal("0.${"1".padLeft(pow(10, 4),"0")}")).toString(), BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").toString());print("Testing random");for(int i=0; i<1000; ++i) {print("\tEvaluating #${i.toString().padLeft(4)} ->");String strReal1 = generateNumber(decimal: false);String strDecimal1 = generateNumber(decimal: true);String number1 = "$strReal1.$strDecimal1";String strReal2 = generateNumber(decimal: false);String strDecimal2 = generateNumber(decimal: true);String number2 = "$strReal2.$strDecimal2";print("\t\t[${strReal1.length.toString().padLeft(5)}].[${strDecimal1.length.toString().padLeft(5)}]:${strReal1.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal1");print("\t\t[${strReal2.length.toString().padLeft(5)}].[${strDecimal2.length.toString().padLeft(5)}]:${strReal2.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal2");BigInt biReal1    = BigInt.parse(strReal1   );BigInt biDecimal1 = BigInt.parse(strDecimal1.padRight(max(strDecimal1.length, strDecimal2.length),"0"));BigInt biReal2    = BigInt.parse(strReal2   );BigInt biDecimal2 = BigInt.parse(strDecimal2.padRight(max(strDecimal1.length, strDecimal2.length),"0"));int compare;if     (strReal1.length>strReal2.length) compare =  1;else if(strReal1.length<strReal2.length) compare = -1;else compare = strReal1.compareTo(strReal2);if(compare==0){String strDecimal3 = strDecimal1.padRight(max(strDecimal1.length, strDecimal2.length),"0");String strDecimal4 = strDecimal2.padRight(max(strDecimal1.length, strDecimal2.length),"0");compare = strDecimal3.compareTo(strDecimal4);}BigInt biDecimal3  = BigInt.zero;String strReal3    = "";String strDecimal3 = "";if(compare==1){biDecimal3 = biDecimal1 - biDecimal2;bool   borrow     = biDecimal3 < BigInt.zero;BigInt biReal3    = biReal1 - biReal2 - (borrow?BigInt.one : BigInt.zero);strReal3   = biReal3.toString();if(borrow) strDecimal3 = (biDecimal3 + BigInt.parse("1".padRight(max(strDecimal1.length, strDecimal2.length)+1,"0"))).toString();else strDecimal3 = biDecimal3.toString();}if(compare==-1){// a-b = -(b-a)biDecimal3 = biDecimal2 - biDecimal1;bool   borrow     = biDecimal3 < BigInt.zero;BigInt biReal3    = biReal2 - biReal1 - (borrow?BigInt.one : BigInt.zero);strReal3   = "-"+biReal3.toString();if(borrow) strDecimal3 = (biDecimal3 + BigInt.parse("1".padRight(max(strDecimal1.length, strDecimal2.length)+1,"0"))).toString();else strDecimal3 = biDecimal3.toString();}if(strDecimal3 != "0"){strDecimal3 = strDecimal3.padLeft(max(strDecimal1.length, strDecimal2.length),"0");while(strDecimal3.length>0){if(strDecimal3.substring(strDecimal3.length-1) == "0"){strDecimal3 = strDecimal3.substring(0, strDecimal3.length-1);continue;}break;}}expect(BigDecimal(number1)-BigDecimal(number2), BigDecimal("$strReal3.$strDecimal3"));}});test("BigDecimal operator * test",()async{print("Testing Basic");expect((BigDecimal("1" )*BigDecimal("1" )).toString(), BigDecimal("1" ).toString());expect((BigDecimal("-1")*BigDecimal("1" )).toString(), BigDecimal("-1").toString());expect((BigDecimal("-1")*BigDecimal("-1")).toString(), BigDecimal("1" ).toString());print("Testing Real");expect((BigDecimal("9".padLeft (10   ,"9"))*BigDecimal.one).toString(), BigDecimal("9".padLeft (10   ,"9")).toString());expect((BigDecimal("9".padLeft (100  ,"9"))*BigDecimal.one).toString(), BigDecimal("9".padLeft (100  ,"9")).toString());expect((BigDecimal("9".padLeft (1000 ,"9"))*BigDecimal.one).toString(), BigDecimal("9".padLeft (1000 ,"9")).toString());expect((BigDecimal("9".padLeft (10000,"9"))*BigDecimal.one).toString(), BigDecimal("9".padLeft (10000,"9")).toString());print("Testing Decimal");expect((BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}")*BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}")*BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}")*BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}")*BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}")*BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").toString());print("Testing random");for(int i=0; i<10000; ++i) {print("\tEvaluating #${i.toString().padLeft(4)} ->");String strReal1 = generateNumber(decimal: false);String strDecimal1 = generateNumber(decimal: true);String number1 = "$strReal1.$strDecimal1";String strReal2 = generateNumber(decimal: false);String strDecimal2 = generateNumber(decimal: true);String number2 = "$strReal2.$strDecimal2";print("\t\t[${strReal1.length.toString().padLeft(5)}].[${strDecimal1.length.toString().padLeft(5)}]:${strReal1.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal1");print("\t\t[${strReal2.length.toString().padLeft(5)}].[${strDecimal2.length.toString().padLeft(5)}]:${strReal2.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal2");BigInt biNum1 = BigInt.parse("$strReal1${strDecimal1.padRight(max(strDecimal1.length, strDecimal2.length),"0")}");BigInt biNum2 = BigInt.parse("$strReal2${strDecimal2.padRight(max(strDecimal1.length, strDecimal2.length),"0")}");BigInt biPow  = BigInt.parse("1".padRight(max(strDecimal1.length,strDecimal2.length)*2+1,"0"));BigInt biNum3 = biNum1 * biNum2;String strReal3 = (biNum3~/biPow).toString();String strDecimal3 = (biNum3%biPow).toString().padLeft(max(strDecimal1.length, strDecimal2.length)*2,"0");while(strDecimal3.length>0){if(strDecimal3.substring(strDecimal3.length-1) == "0"){strDecimal3 = strDecimal3.substring(0, strDecimal3.length-1);continue;}break;}expect(BigDecimal(number1)*BigDecimal(number2), BigDecimal("$strReal3.$strDecimal3"));}print("Test Passed");});test("BigDecimal operator / test",()async{print("Testing Basic");expect((BigDecimal("1" ).disablePrecisionLimit()/BigDecimal("0.1" )).toString(), BigDecimal("10").toString());expect((BigDecimal("1" ).disablePrecisionLimit()/BigDecimal("1"   )).toString(), BigDecimal("1" ).toString());expect((BigDecimal("-1").disablePrecisionLimit()/BigDecimal("1"   )).toString(), BigDecimal("-1").toString());expect((BigDecimal("-1").disablePrecisionLimit()/BigDecimal("-1"  )).toString(), BigDecimal("1" ).toString());print("Testing Real");expect((BigDecimal("9".padLeft (10   ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (10   ,"9")).toString());expect((BigDecimal("9".padLeft (100  ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (100  ,"9")).toString());expect((BigDecimal("9".padLeft (1000 ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (1000 ,"9")).toString());expect((BigDecimal("9".padLeft (10000,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (10000,"9")).toString());print("Testing Decimal");expect((BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").toString());print("Testing random");for(int i=0; i<1000; ++i) {print("\tEvaluating #${i.toString().padLeft(4)} ->");String strReal1    = generateNumber(decimal: false, maxLength: 50);String strDecimal1 = generateNumber(decimal: true , maxLength: 50);String number1     = "$strReal1.$strDecimal1";String strReal2    = generateNumber(decimal: false, maxLength: 50);String strDecimal2 = generateNumber(decimal: true , maxLength: 50);String number2     = "$strReal2.$strDecimal2";print("\t\t[${strReal1.length.toString().padLeft(5)}].[${strDecimal1.length.toString().padLeft(5)}]:${strReal1.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal1");print("\t\t[${strReal2.length.toString().padLeft(5)}].[${strDecimal2.length.toString().padLeft(5)}]:${strReal2.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal2");StringBuilder sbDiv             = StringBuilder();int           nRealBitPrecision = strReal1.length + strDecimal2.length;int           pPrecision        = -nRealBitPrecision;int           char0             = "0".codeUnitAt(0);BigInt        biTen             = BigInt.from(10);String        strNum1           = "$strReal1$strDecimal1";BigInt        dividend          = BigInt.zero;BigInt        divisor           = BigInt.parse("$strReal2$strDecimal2");for(int i=0; i<strNum1.length || dividend!=BigInt.zero; ++i){if(pPrecision++>=1000) break;int num = i<strNum1.length ? (strNum1.codeUnitAt(i)-char0) : 0;dividend = dividend*biTen + BigInt.from(num);if(dividend<divisor){sbDiv.append(0);continue;}BigInt quotient  = dividend~/divisor;BigInt remainder = dividend%divisor;sbDiv.append(quotient.toString());dividend = remainder;}String strReal3    = sbDiv.substring(0                , nRealBitPrecision);String strDecimal3 = sbDiv.substring(nRealBitPrecision);while(strReal3.length>0){if(strReal3.substring(0,1) == "0"){strReal3 = strReal3.substring(1);continue;}break;}while(strDecimal3.length>0){if(strDecimal3.substring(strDecimal3.length-1) == "0"){strDecimal3 = strDecimal3.substring(0, strDecimal3.length-1);continue;}break;}expect(BigDecimal(number1)/BigDecimal(number2), BigDecimal("$strReal3.$strDecimal3"));}print("Test Passed");});test("BigDecimal operator / test 2",()async{print("Testing Basic");expect((BigDecimal("1" ).disablePrecisionLimit()/BigDecimal("0.1" )).toString(), BigDecimal("10").toString());expect((BigDecimal("1" ).disablePrecisionLimit()/BigDecimal("1"   )).toString(), BigDecimal("1" ).toString());expect((BigDecimal("-1").disablePrecisionLimit()/BigDecimal("1"   )).toString(), BigDecimal("-1").toString());expect((BigDecimal("-1").disablePrecisionLimit()/BigDecimal("-1"  )).toString(), BigDecimal("1" ).toString());print("Testing Real");expect((BigDecimal("9".padLeft (10   ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (10   ,"9")).toString());expect((BigDecimal("9".padLeft (100  ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (100  ,"9")).toString());expect((BigDecimal("9".padLeft (1000 ,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (1000 ,"9")).toString());expect((BigDecimal("9".padLeft (10000,"9")).disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("9".padLeft (10000,"9")).toString());print("Testing Decimal");expect((BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 0),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 1),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 2),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 3),"9")}").toString());expect((BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").disablePrecisionLimit()/BigDecimal.one).toString(), BigDecimal("0.${"9".padLeft(pow(10, 4),"9")}").toString());print("Testing random");for(int i=0; i<10000; ++i) {print("\tEvaluating #${i.toString().padLeft(4)} ->");String strReal1    = generateNumber(decimal: false, maxLength: 50);String strDecimal1 = generateNumber(decimal: true, maxLength: 50);String number1     = "$strReal1.$strDecimal1";String strReal2    = generateNumber(decimal: false, maxLength: 50);String strDecimal2 = generateNumber(decimal: true, maxLength: 50);String number2     = "$strReal2.$strDecimal2";print("\t\t[${strReal1.length.toString().padLeft(5)}].[${strDecimal1.length.toString().padLeft(5)}]:${strReal1.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal1");print("\t\t[${strReal2.length.toString().padLeft(5)}].[${strDecimal2.length.toString().padLeft(5)}]:${strReal2.padLeft(max(strReal1.length, strReal2.length)," ")}.$strDecimal2");BigDecimal bd1 = BigDecimal(number1);BigDecimal bd2 = BigDecimal(number2);BigDecimal bd3 = bd1*bd2;expect(bd3.disablePrecisionLimit()/bd2, bd1);}print("Test Passed");},);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件应用,宠物医院兽医开的处方单管理系统软件教程,宠物店营业软件教程

软件应用&#xff0c;宠物医院兽医开的处方单管理系统软件教程&#xff0c;宠物店营业软件教程 一、前言 以下软件操作教程以 佳易王宠物医院兽医处方软件V17.0为例说明 件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 在开处方单的时候&#xff0c;可以打…

工程信号的去噪和(分类、回归和时序)预测

&#x1f680;【信号去噪及预测论文代码指导】&#x1f680; 还为小论文没有思路烦恼么&#xff1f;本人专注于最前沿的信号处理与预测技术——基于信号模态分解的去噪算法和深度学习的信号&#xff08;回归、时序和分类&#xff09;预测算法&#xff0c;致力于为您提供最精确、…

硬核分享|免费快速的高保真图片压缩方案

硬核分享|免费快速的高保真图片压缩方案_哔哩哔哩_bilibili 在当今数字化时代&#xff0c;图像已然成为我们日常生活中必不可少的元素之一。但是&#xff0c;伴随着高清相机与日俱增以及拍摄照片数量的飞速增长&#xff0c;如何安全、高效的存储和传播海量图片已逐渐成为亟待解…

【NLP6-使用seq2seq模型架构实现英译法任务】

使用seq2seq模型架构实现英译法任务 目标 1、更深一步了解seq2seq模型架构和翻译数据集 2、掌握适用基于GRU的seq2seq模型实现翻译过程 3、掌握Attention机制在解码器端的实现过程 seq2seq模型架构 encoder编码器 Decoder解码器 数据预览 基于GRU的seq2seq模型架构实现…

户外水质检测显示屏用于检测并显示各种水质数据

水质检测一直是环境保护和公共卫生领域的重要课题。随着科技的不断进步&#xff0c;水质检测设备也在不断更新换代。其中&#xff0c;水质检测显示屏作为一种新型的检测设备&#xff0c;为监测和显示各种水质数据提供了便利和高效的手段。 水质检测显示屏是一种集成了传感器、数…

CSS 让元素根据内容自适应宽度

一、需求 点击链接跳转&#xff0c;只点击标红区域才跳转&#xff0c;右侧空白区域不要跳转 二、实现 宽度太宽&#xff0c;导致右侧空白区域也加了跳转效果&#xff0c;修改为 将元素的最大宽度设置为其内容所需的宽度。 方法一&#xff1a;建议方式 使用 display: inline…

Excel的数据分析工具

Excel的数据分析工具 会生成新的工作簿 全选--数据透视表 插入切片器 使用作图工具 可以继续插入条件切片

数据结构:图的拓扑排序与关键路径

目录 一、拓扑排序 1.1、算法的基本步骤 1.2、算法实现 1.3、习题思考 1.4、DFS生成逆拓扑序 二、关键路径 1.1、关键路径的原理 1.2、算法的基本步骤 1.3、算法实现 1.4、习题思考 一、拓扑排序 ➢ AOV网:在 有向图中&#xff0c; 顶点表示活动&#xff08;或任务&a…

Android ViewPager不支持wrap_content的原因

文章目录 Android ViewPager不支持wrap_content的原因问题源码分析解决 Android ViewPager不支持wrap_content的原因 问题 <androidx.viewpager.widget.ViewPagerandroid:id"id/wrap_view_pager"android:layout_width"match_parent"android:layout_he…

【氮化镓】利用Ga2O3缓冲层改善SiC衬底AlN/GaN/AlGaN HEMT器件性能

Micro and Nanostructures 189 (2024) 207815文献于阅读总结。 本文是关于使用SiC衬底AlN/GaN/AlGaN高电子迁移率晶体管&#xff08;HEMT&#xff09;的研究&#xff0c;特别是探讨了不同缓冲层对器件性能的影响&#xff0c;以应用于高速射频&#xff08;RF&#xff09;应用。…

ClickHouse01-什么是ClickHouse

什么是ClickHouse&#xff1f; 关于发展历史存在的优势与劣势什么是它风靡的原因&#xff1f; 什么是ClickHouse&#xff1f; 官方给出的回答是&#xff0c;它是一个高性能、列式存储、基于SQL、供在线分析处理的数据库管理系统 当然这边不得不提到OLAP(Online Analytical Pr…

《Java开发实战》课程

1、按以下要求编写程序 (1) 创建一个Rectangle类,添加width和height两个成员变量; (2) 在Rectangle中添加两种方法分别计算矩形的周长和面积; (3) 编程利用Rectangle输出一个矩形的周长和面积(长和宽由用户从键盘输入); import java.util.Scanner;public class Recta…

信息学奥赛之MAC端VSCode C++环境配置

前提 安装 Visual Studio CodeVSCode 中安装 C/C扩展确保 Clang 已经安装&#xff08;在终端中输入命令&#xff1a;clang --version 来确认是否安装&#xff09;未安装&#xff0c;在命令行执行xcode-select --install 命令&#xff0c;会自行安装&#xff0c;安装文件有点大…

ideaSSM博物馆网站系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 博物馆网站系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c…

爬虫分析-基于Python的空气质量数据分析与实践

概要 本篇文章利用了Python爬虫技术对空气质量网站的数据进行获取&#xff0c;获取之后把数据生成CSV格式的文件&#xff0c;然后再存入数据库方便保存。再从之前24小时的AQI&#xff08;空气质量指数&#xff09;的平均值中进行分析,把数据取出来后&#xff0c;对数据进行数据…

android 实现息屏亮屏 Runtime.getRuntime().exec不执行

公司想实现远程息屏亮屏。试了下PowerManager&#xff0c;对我这个广告屏来讲是没有效果的。 import android.content.Context; import android.os.PowerManager;public class ScreenStateHelper {private PowerManager powerManager;private WakeLock wakeLock;public Screen…

第12篇:4线-2线普通编码器

Q&#xff1a;在数字系统中&#xff0c;用一个二进制代码表示特定信息称为编码&#xff0c;而具有编码功能的逻辑电路就称为编码器。本期我们学习实现4线-2线普通编码器。 A&#xff1a;基本原理&#xff1a;二进制编码器有n位输出&#xff0c;与个输入相对应。4线-2线普通编码…

前端与后端具备能力的区别

前端与后端具备能力的区别 在软件开发领域&#xff0c;前端和后端是两个至关重要的部分&#xff0c;它们各自承担着不同的职责和任务。前端主要负责与用户交互的界面设计和实现&#xff0c;而后端则负责处理数据和业务逻辑。因此&#xff0c;前端和后端开发者需要具备不同的技…

mysql 如何设计分库分表

在MySQL中设计分库分表的方法通常涉及到水平拆分与垂直拆分两种主要方式。 水平拆分&#xff1a; 按照某一列进行水平拆分&#xff1a; 可以根据某一列&#xff08;如用户ID、时间等&#xff09;的取值范围将数据拆分到不同的数据库或表中。基于哈希值的水平拆分&#xff1a;…