1. package com.vivo.ars.util;
    2. import java.math.BigDecimal;
    3. /**
    4. * 用于高精确处理常用的数学运算
    5. */
    6. public class ArithmeticUtils {
    7. //默认除法运算精度
    8. private static final int DEF_DIV_SCALE = 10;
    9. /**
    10. * 提供精确的加法运算
    11. *
    12. * @param v1 被加数
    13. * @param v2 加数
    14. * @return 两个参数的和
    15. */
    16. public static double add(double v1, double v2) {
    17. BigDecimal b1 = new BigDecimal(Double.toString(v1));
    18. BigDecimal b2 = new BigDecimal(Double.toString(v2));
    19. return b1.add(b2).doubleValue();
    20. }
    21. /**
    22. * 提供精确的加法运算
    23. *
    24. * @param v1 被加数
    25. * @param v2 加数
    26. * @return 两个参数的和
    27. */
    28. public static BigDecimal add(String v1, String v2) {
    29. BigDecimal b1 = new BigDecimal(v1);
    30. BigDecimal b2 = new BigDecimal(v2);
    31. return b1.add(b2);
    32. }
    33. /**
    34. * 提供精确的加法运算
    35. *
    36. * @param v1 被加数
    37. * @param v2 加数
    38. * @param scale 保留scale 位小数
    39. * @return 两个参数的和
    40. */
    41. public static String add(String v1, String v2, int scale) {
    42. if (scale < 0) {
    43. throw new IllegalArgumentException(
    44. "The scale must be a positive integer or zero");
    45. }
    46. BigDecimal b1 = new BigDecimal(v1);
    47. BigDecimal b2 = new BigDecimal(v2);
    48. return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    49. }
    50. /**
    51. * 提供精确的减法运算
    52. *
    53. * @param v1 被减数
    54. * @param v2 减数
    55. * @return 两个参数的差
    56. */
    57. public static double sub(double v1, double v2) {
    58. BigDecimal b1 = new BigDecimal(Double.toString(v1));
    59. BigDecimal b2 = new BigDecimal(Double.toString(v2));
    60. return b1.subtract(b2).doubleValue();
    61. }
    62. /**
    63. * 提供精确的减法运算。
    64. *
    65. * @param v1 被减数
    66. * @param v2 减数
    67. * @return 两个参数的差
    68. */
    69. public static BigDecimal sub(String v1, String v2) {
    70. BigDecimal b1 = new BigDecimal(v1);
    71. BigDecimal b2 = new BigDecimal(v2);
    72. return b1.subtract(b2);
    73. }
    74. /**
    75. * 提供精确的减法运算
    76. *
    77. * @param v1 被减数
    78. * @param v2 减数
    79. * @param scale 保留scale 位小数
    80. * @return 两个参数的差
    81. */
    82. public static String sub(String v1, String v2, int scale) {
    83. if (scale < 0) {
    84. throw new IllegalArgumentException(
    85. "The scale must be a positive integer or zero");
    86. }
    87. BigDecimal b1 = new BigDecimal(v1);
    88. BigDecimal b2 = new BigDecimal(v2);
    89. return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    90. }
    91. /**
    92. * 提供精确的乘法运算
    93. *
    94. * @param v1 被乘数
    95. * @param v2 乘数
    96. * @return 两个参数的积
    97. */
    98. public static double mul(double v1, double v2) {
    99. BigDecimal b1 = new BigDecimal(Double.toString(v1));
    100. BigDecimal b2 = new BigDecimal(Double.toString(v2));
    101. return b1.multiply(b2).doubleValue();
    102. }
    103. /**
    104. * 提供精确的乘法运算
    105. *
    106. * @param v1 被乘数
    107. * @param v2 乘数
    108. * @return 两个参数的积
    109. */
    110. public static BigDecimal mul(String v1, String v2) {
    111. BigDecimal b1 = new BigDecimal(v1);
    112. BigDecimal b2 = new BigDecimal(v2);
    113. return b1.multiply(b2);
    114. }
    115. /**
    116. * 提供精确的乘法运算
    117. *
    118. * @param v1 被乘数
    119. * @param v2 乘数
    120. * @param scale 保留scale 位小数
    121. * @return 两个参数的积
    122. */
    123. public static double mul(double v1, double v2, int scale) {
    124. BigDecimal b1 = new BigDecimal(Double.toString(v1));
    125. BigDecimal b2 = new BigDecimal(Double.toString(v2));
    126. return round(b1.multiply(b2).doubleValue(), scale);
    127. }
    128. /**
    129. * 提供精确的乘法运算
    130. *
    131. * @param v1 被乘数
    132. * @param v2 乘数
    133. * @param scale 保留scale 位小数
    134. * @return 两个参数的积
    135. */
    136. public static String mul(String v1, String v2, int scale) {
    137. if (scale < 0) {
    138. throw new IllegalArgumentException(
    139. "The scale must be a positive integer or zero");
    140. }
    141. BigDecimal b1 = new BigDecimal(v1);
    142. BigDecimal b2 = new BigDecimal(v2);
    143. return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    144. }
    145. /**
    146. * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
    147. * 小数点以后10位,以后的数字四舍五入
    148. *
    149. * @param v1 被除数
    150. * @param v2 除数
    151. * @return 两个参数的商
    152. */
    153. public static double div(double v1, double v2) {
    154. return div(v1, v2, DEF_DIV_SCALE);
    155. }
    156. /**
    157. * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
    158. * 定精度,以后的数字四舍五入
    159. *
    160. * @param v1 被除数
    161. * @param v2 除数
    162. * @param scale 表示表示需要精确到小数点以后几位。
    163. * @return 两个参数的商
    164. */
    165. public static double div(double v1, double v2, int scale) {
    166. if (scale < 0) {
    167. throw new IllegalArgumentException("The scale must be a positive integer or zero");
    168. }
    169. BigDecimal b1 = new BigDecimal(Double.toString(v1));
    170. BigDecimal b2 = new BigDecimal(Double.toString(v2));
    171. return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    172. }
    173. /**
    174. * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
    175. * 定精度,以后的数字四舍五入
    176. *
    177. * @param v1 被除数
    178. * @param v2 除数
    179. * @param scale 表示需要精确到小数点以后几位
    180. * @return 两个参数的商
    181. */
    182. public static String div(String v1, String v2, int scale) {
    183. if (scale < 0) {
    184. throw new IllegalArgumentException("The scale must be a positive integer or zero");
    185. }
    186. BigDecimal b1 = new BigDecimal(v1);
    187. BigDecimal b2 = new BigDecimal(v1);
    188. return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
    189. }
    190. /**
    191. * 提供精确的小数位四舍五入处理
    192. *
    193. * @param v 需要四舍五入的数字
    194. * @param scale 小数点后保留几位
    195. * @return 四舍五入后的结果
    196. */
    197. public static double round(double v, int scale) {
    198. if (scale < 0) {
    199. throw new IllegalArgumentException("The scale must be a positive integer or zero");
    200. }
    201. BigDecimal b = new BigDecimal(Double.toString(v));
    202. return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    203. }
    204. /**
    205. * 提供精确的小数位四舍五入处理
    206. *
    207. * @param v 需要四舍五入的数字
    208. * @param scale 小数点后保留几位
    209. * @return 四舍五入后的结果
    210. */
    211. public static String round(String v, int scale) {
    212. if (scale < 0) {
    213. throw new IllegalArgumentException(
    214. "The scale must be a positive integer or zero");
    215. }
    216. BigDecimal b = new BigDecimal(v);
    217. return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    218. }
    219. /**
    220. * 取余数
    221. *
    222. * @param v1 被除数
    223. * @param v2 除数
    224. * @param scale 小数点后保留几位
    225. * @return 余数
    226. */
    227. public static String remainder(String v1, String v2, int scale) {
    228. if (scale < 0) {
    229. throw new IllegalArgumentException(
    230. "The scale must be a positive integer or zero");
    231. }
    232. BigDecimal b1 = new BigDecimal(v1);
    233. BigDecimal b2 = new BigDecimal(v2);
    234. return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    235. }
    236. /**
    237. * 取余数 BigDecimal
    238. *
    239. * @param v1 被除数
    240. * @param v2 除数
    241. * @param scale 小数点后保留几位
    242. * @return 余数
    243. */
    244. public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
    245. if (scale < 0) {
    246. throw new IllegalArgumentException(
    247. "The scale must be a positive integer or zero");
    248. }
    249. return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    250. }
    251. /**
    252. * 比较大小
    253. *
    254. * @param v1 被比较数
    255. * @param v2 比较数
    256. * @return 如果v1 大于v2 则 返回true 否则false
    257. */
    258. public static boolean compare(String v1, String v2) {
    259. BigDecimal b1 = new BigDecimal(v1);
    260. BigDecimal b2 = new BigDecimal(v2);
    261. int bj = b1.compareTo(b2);
    262. boolean res;
    263. if (bj > 0)
    264. res = true;
    265. else
    266. res = false;
    267. return res;
    268. }
    269. }