fix
Helius
2021-08-05 8bbb027dc36b3f3c7f2d505fc75180261fb4d640
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
package com.xzx.gc.util;
 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Random;
import java.util.regex.Pattern;
 
@Slf4j
public class DoubleUtil {
 
    // 默认除法运算精度
    private static final Integer DEF_DIV_SCALE = 10;
    private static final String REGEX_MOBILE ="((\\+86|0086)?\\s*)((134[0-8]\\d{7})|(((13([0-3]|[5-9]))|(14[5-9])|15([0-3]|[5-9])|(16(2|[5-7]))|17([0-3]|[5-8])|18[0-9]|19(1|[8-9]))\\d{8})|(14(0|1|4)0\\d{7})|(1740([0-5]|[6-9]|[10-12])\\d{7}))";
    static Random random = new Random();
    static {
        random.setSeed(System.currentTimeMillis());
    }
    /**
     * 提供精确的加法运算。
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    public static Double add(Double value1, Double value2) {
        BigDecimal b1 = new BigDecimal(Double.toString(value1));
        BigDecimal b2 = new BigDecimal(Double.toString(value2));
        return b1.add(b2).doubleValue();
    }
 
    /**
     * 提供精确的减法运算。
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    public static double sub(Double value1, Double value2) {
        BigDecimal b1 = new BigDecimal(Double.toString(value1));
        BigDecimal b2 = new BigDecimal(Double.toString(value2));
        return b1.subtract(b2).doubleValue();
    }
 
    /**
     * 提供精确的乘法运算。
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    public static Double mul(Double value1, Double value2) {
        BigDecimal b1 = new BigDecimal(Double.toString(value1));
        BigDecimal b2 = new BigDecimal(Double.toString(value2));
        return b1.multiply(b2).doubleValue();
    }
 
    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。
     * @param dividend 被除数
     * @param divisor 除数
     * @return 两个参数的商
     */
    public static Double divide(Double dividend, Double divisor) {
        if(divisor.intValue() == 0){ return 0.0;}
        return divide(dividend, divisor, DEF_DIV_SCALE);
    }
 
    /**
     * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
     * @param dividend 被除数
     * @param divisor 除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static Double divide(Double dividend, Double divisor, Integer scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(dividend));
        BigDecimal b2 = new BigDecimal(Double.toString(divisor));
        return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
    }
 
 
    public static String roundThree(String value){
        DecimalFormat format = new DecimalFormat("0.000");
        return format.format(new BigDecimal(value));
    }
    public static String roundTwo(String value){
        DecimalFormat format = new DecimalFormat("0.00");
        return format.format(new BigDecimal(value));
    }
    public static String roundSix(String value){
        DecimalFormat format = new DecimalFormat("0.000000");
        return format.format(new BigDecimal(value));
    }
    public static String roundFive(String value){
        DecimalFormat format = new DecimalFormat("0.00000");
        return format.format(new BigDecimal(value));
    }
    public static String roundOne(String value){
        DecimalFormat format = new DecimalFormat("0.0");
        return format.format(new BigDecimal(value));
    }
 
    public static Double roundByScale(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "保留位数不能小于0!");
        }
        if(scale == 0){
            return new Double("0");
        }
        String formatStr = "0.";
        for(int i=0;i<scale;i++){
            formatStr = formatStr + "0";
        }
        String str =  new DecimalFormat(formatStr).format(v);
 
        DecimalFormat df = new DecimalFormat(formatStr);
        System.out.println(str);
        return  Double.parseDouble(str);
    }
 
 
 
 
 
    public static double restRound(double min,double max,int i,double money,int count){
        double redpac=0;
        if(i==19){
            redpac=money;
        }else{
            redpac=(Math.random()*(max-min)+min)/100;
        }
        return redpac;
    }
 
 
    /**
     * 生产min和max之间的随机数,但是概率不是平均的,从min到max方向概率逐渐加大。
     * 先平方,然后产生一个平方值范围内的随机数,再开方,这样就产生了一种“膨胀”再“收缩”的效果。
     *
     * @param min
     * @param max
     * @return
     */
    static long xRandom(long min, long max) {
        return sqrt(nextLong(sqr(max - min)));
    }
 
    /**
     *
     * @param totalStr
     *            红包总额
     * @param count
     *            红包个数
     * @param maxStr
     *            每个小红包的最大额
     * @param minStr
     *            每个小红包的最小额
     * @return 存放生成的每个小红包的值的数组
     */
    public static long[] generate(String totalStr, int count, String maxStr, String minStr) {
 
        double mind = Double.parseDouble(minStr)*100;
        double maxd = Double.parseDouble(maxStr)*100;
        double totald = Double.parseDouble(totalStr)*100;
 
        log.debug(mind+"========"+maxd);
 
        long min = new Double(mind).longValue();
        long max = new Double(maxd).longValue();
        long total =new Double(totald).longValue();
 
        long[] result = new long[count];
 
        long average = total / count;
 
        long a = average - min;
        long b = max - min;
 
        //这样的随机数的概率实际改变了,产生大数的可能性要比产生小数的概率要小。
        //这样就实现了大部分红包的值在平均数附近。大红包和小红包比较少。
        long range1 = sqr(average - min);
        long range2 = sqr(max - average);
 
        for (int i = 0; i < result.length; i++) {
            //因为小红包的数量通常是要比大红包的数量要多的,因为这里的概率要调换过来。
            //当随机数>平均值,则产生小红包
            //当随机数<平均值,则产生大红包
            if (nextLong(min, max) > average) {
                // 在平均线上减钱
//                long temp = min + sqrt(nextLong(range1));
                long temp = min + xRandom(min, average);
                result[i] = temp;
                total -= temp;
            } else {
                // 在平均线上加钱
//                long temp = max - sqrt(nextLong(range2));
                long temp = max - xRandom(average, max);
                result[i] = temp;
                total -= temp;
            }
        }
        // 如果还有余钱,则尝试加到小红包里,如果加不进去,则尝试下一个。
        while (total > 0) {
            for (int i = 0; i < result.length; i++) {
                if (total > 0 && result[i] < max) {
                    result[i]++;
                    total--;
                }
            }
        }
        // 如果钱是负数了,还得从已生成的小红包中抽取回来
        while (total < 0) {
            for (int i = 0; i < result.length; i++) {
                if (total < 0 && result[i] > min) {
                    result[i]--;
                    total++;
                }
            }
        }
        return result;
    }
 
    static long sqrt(long n) {
        // 改进为查表?
        return (long) Math.sqrt(n);
    }
 
    static long sqr(long n) {
        // 查表快,还是直接算快?
        return n * n;
    }
 
    static long nextLong(long n) {
        return random.nextInt((int) n);
    }
 
    static long nextLong(long min, long max) {
        return random.nextInt((int) (max - min + 1)) + min;
    }
 
    public static void main(String[] args) {
           // System.out.println(roundByScale(new Double("1.10"),2));
        //double min_money=5; // 每个人最少能收到0.05元、
        //double max_money=20; // 每个人最少能收到0.05元、
        //randomPackage(100,10,40,2000);
        //long max = 2000;
        //long min = 40;
        //System.out.println(getStringRandom(6));
    }
    /**
     * 判断是否是手机号
     * @param tel 手机号
     * @return boolean true:是  false:否
     */
    public static boolean isMobile(String tel) {
        if (StringUtils.isEmpty(tel)){ return false;}
        return Pattern.matches(REGEX_MOBILE, tel);
    }
 
 
    /**
     * 使用java正则表达式去掉多余的.与0
     * @param s
     * @return
     */
    public static String subZeroAndDot(String s){
        if(StringUtils.isBlank(s)){
            return null;
        }
        if(s.indexOf(".") > 0){
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }
 
    public static String getLowerLetterNumber(int length) {
        String str = "0123456789abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; ++i) {
            sb.append(str.charAt(random.nextInt(46)));
        }
        return sb.toString();
    }
 
}