notice:
- 平均红包金额不能低于0.01元
- 对浮点数四则运算和四舍五入的处理
1 <script> 2 //调用方法 3 getRedPacket(10,10); 4 5 /* 6 * @description:抢红包算法 7 * @params {Number} money 总金额 8 * @params {Number} num 红包总个数 9 * @return {Number} 10 * */ 11 function getRedPacket(money,num) { 12 var redPacketArr = [], //记录分配的红包金额 13 remainMoney = money, //剩余的红包金额 14 avgMoney = doDivision(money,num); //平均分得的红包金额 15 switch (num){ 16 case 0: 17 alert('红包个数不能为0'); 18 break; 19 case 1: 20 redPacketArr.push(money); 21 break; 22 default: 23 let randomIndex = 0, //最后一个数在redPacketArr的位置 24 last = 0; //计算最后一个数 25 26 if(avgMoney < 0.01){ 27 alert('单个红包金额不低于0.01元'); 28 return; 29 } 30 for(let i = 1; i < num; i++){ //计算总数量-1个 31 let random = Math.random(); 32 let randomMoney = random*rewriteToFixed(avgMoney,4), //随机值,保留4位小数(更精确) 33 val = rewriteToFixed(randomMoney,2); //随机值保留2为小数(钱的单位不能低于分) 34 if(val != 0){ 35 remainMoney = doSubtraction(remainMoney,val); 36 redPacketArr.push(val); 37 }else { 38 i--; 39 } 40 } 41 last = redPacketArr.reduce((x,y) => doAdditive(x,y)); 42 randomIndex = Math.floor(Math.random()*redPacketArr.length); 43 redPacketArr.splice(randomIndex,0,rewriteToFixed(doSubtraction(money,last),2)); //把最大金额随机插入redPacketArr中 44 } 45 console.log(redPacketArr); 46 return redPacketArr; 47 } 48 /* 49 * @description:重写toFixed方法 50 * @params {Number} value,num 51 * @return {Number} 52 * */ 53 function rewriteToFixed(value,num) { 54 let str = '' + value, 55 index = str.indexOf('.'), //小数点的位置 56 sliIndex = index + num + 1, 57 s1 = str.slice(0,sliIndex), 58 nextNum = Number(str.slice(sliIndex,sliIndex + 1)); 59 if(nextNum > 5){ 60 s1 = s1.replace(/d$/,v => Number(v)+1); 61 } 62 return Number(s1); 63 } 64 /* 65 * @description:浮点数相加 66 * @params {Number} n1,n2 67 * @return {Number} 68 * */ 69 function doAdditive(n1,n2) { 70 let e = commonCode(n1,n2); 71 return (n1*e + n2*e)/e; 72 } 73 74 /* 75 * @description:浮点数相减 76 * @params {Number} n1,n2 77 * @return {Number} 78 * */ 79 function doSubtraction(n1,n2) { 80 let e = commonCode(n1,n2); 81 return (n1*e - n2*e)/e; 82 } 83 84 /* 85 * @description:浮点数相乘 86 * @params {Number} n1,n2 87 * @return {Number} 88 * */ 89 function doMultiplication(n1,n2) { 90 let e = commonCode(n1,n2); 91 return (n1*e) * (n2*e) / Math.pow(e,2); 92 } 93 94 /* 95 * @description:浮点数相除 96 * @params {Number} n1,n2 97 * @return {Number} 98 * */ 99 function doDivision(n1,n2) { 100 let e = commonCode(n1,n2); 101 return (n1*e) / (n2*e); 102 } 103 104 /* 105 * @description:公共代码 106 * @params {Number} n1,n2 107 * @return {Number} e 将n1和n2带小数带转成整型 108 * */ 109 function commonCode(n1,n2) { 110 let len1 = 0, 111 len2 = 0, 112 str1 = ('' + n1), 113 str2 = ('' + n2); 114 if(/./g.test(str1)){ 115 len1 = str1.split('.')[1].length; //n1小数长度 //toString()或String()用于小数后不超过7位 116 } 117 if(/./g.test(str2)){ 118 len2 = str2.split('.')[1].length; //n2小数长度 119 } 120 return Math.pow(10,Math.max(len1,len2)); 121 } 122 </script>