好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java中求Logn/log2 的精度问题

java求Logn/log2精度

经过本人测试,java 中 , 一直到 2的492 次方(这么大的数,平时够用了) ;用 Math.log(n) / Math.log(x) 公式都会产生一个整数

例如

?

1

2

3

int x = 2 ; 

double n = Math.pow( 2 , 234 )

System.out.println(Math.log(n) / Math.log(x));

输出的是 234.0

而到了 2的493次方,结果是493.00000000000006 ; 所以,平时用这个公式来确定n是否是2的整数次幂足够了!

程序如下:

?

1

2

3

4

5

6

7

8

public class Test {

  public static void main(String[] args) { 

  // System.out.println(Math.pow(2, 23)); 

   int x = 2 ; 

   double n = Math.pow( 2 , 493 ) ; 

   System.out.println(Math.log(n) / Math.log(x)); 

  }

}

java 处理高精度计算

Double.valueOf(String) and Float.valueOf(String)都会丢失精度。

为了解决这个问题,需要用到BigDecimal类。

使用的BigDecimal类的时候需要注意的地方:

1. 在实例化BigDecimal 的时候用 new BigDecimal(String) 代替new BigDecimal(double) ,new BigDecimal(float)在《Effective Java》书中有提到

2. 比较两个数的时候用compareTo 小于返回-1 , 等于返回0 , 大于返回1

?

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

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

import java.math.BigDecimal;

public class ArithmeticUtil { 

     /*

      * 小数精确的位数

      */

     private static final int DEF_DIV_SCALE = 10;

 

     /**

      * 提供精确的加法运算。

      *

      * @param v1

      *            被加数

      * @param v2

      *            加数

      * @return 两个参数的和

      */

     public static double add(double v1, double v2) {

         BigDecimal b1 = new BigDecimal(Double.toString(v1));

         BigDecimal b2 = new BigDecimal(Double.toString(v2));

         return b1.add(b2).doubleValue();

     }

   

     /**

      * 提供精确的加法运算。

      *

      * @param v1

      *            被加数

      * @param v2

      *            加数

      * @return 两个参数的和

      */

     public static BigDecimal add(String v1, String v2) {

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.add(b2);

     }

   

     /**

      * 提供精确的加法运算。 String

      *

      * @param v1

      *            被加数

      * @param v2

      *            加数

      * @return 两个参数的和

      */

     public static String strAdd(String v1, String v2,int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

     }

     /**

      * 提供精确的减法运算。

      *

      * @param v1

      *            被减数

      * @param v2

      *            减数

      * @return 两个参数的差

      */

     public static double sub(double v1, double v2) {

         BigDecimal b1 = new BigDecimal(Double.toString(v1));

         BigDecimal b2 = new BigDecimal(Double.toString(v2));

         return b1.subtract(b2).doubleValue();

     }

   

     /**

      * 提供精确的减法运算。

      *

      * @param v1

      *            被减数

      * @param v2

      *            减数

      * @return 两个参数的差

      */

     public static BigDecimal sub(String v1, String v2) {

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.subtract(b2);

     }

   

     /**

      * 对一个数字取精度

      * @param v

      * @param scale

      * @return

      */

     public static BigDecimal round(String v, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b = new BigDecimal(v);

         BigDecimal one = new BigDecimal("1");

         return b.divide(one, scale, BigDecimal.ROUND_HALF_UP);

     }

   

     /**

      * 提供精确的减法运算。String

      *

      * @param v1

      *            被减数

      * @param v2

      *            减数

      * @return 两个参数的差

      */

     public static String strSub(String v1, String v2,int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

     }

     /**

      * 提供精确的乘法运算。

      *

      * @param v1

      *            被乘数

      * @param v2

      *            乘数

      * @return 两个参数的积

      */

     public static double mul(double v1, double v2) {

         BigDecimal b1 = new BigDecimal(Double.toString(v1));

         BigDecimal b2 = new BigDecimal(Double.toString(v2));

         return b1.multiply(b2).doubleValue();

     }

   

     /**

      * 提供精确的乘法运算。

      *

      * @param v1

      *            被乘数

      * @param v2

      *            乘数

      * @return 两个参数的积

      */

     public static BigDecimal mul(String v1, String v2) {

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.multiply(b2);

     }

   

     /**

      * 提供精确的乘法运算。 保留scale 位小数

      *

      * @param v1

      *            被乘数

      * @param v2

      *            乘数

      * @return 两个参数的积

      */

     public static double mul2(double v1, double v2,int scale) {

         BigDecimal b1 = new BigDecimal(Double.toString(v1));

         BigDecimal b2 = new BigDecimal(Double.toString(v2));

         return  round(b1.multiply(b2).doubleValue(),scale);

     }

   

     /**

      * 提供精确的乘法运算。 保留scale 位小数 String

      *

      * @param v1

      *            被乘数

      * @param v2

      *            乘数

      * @return 两个参数的积

      */

     public static String strMul2(String v1, String v2,int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

     }

     /**

      * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @return 两个参数的商

      */

     public static BigDecimal div(String v1, String v2) {

         return div(v1, v2, DEF_DIV_SCALE);

     }

   

     /**

      * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @return 两个参数的商

      */

     public static double div(double v1, double v2) {

         return div(v1, v2, DEF_DIV_SCALE);

     }

 

     /**

      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @param scale

      *            表示需要精确到小数点以后几位。

      * @return 两个参数的商

      */

     public static double div(double v1, double v2, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(Double.toString(v1));

         BigDecimal b2 = new BigDecimal(Double.toString(v2));

         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

     }

   

     /**

      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @param scale

      *            表示需要精确到小数点以后几位。

      * @return 两个参数的商

      */

     public static BigDecimal div(String v1, String v2, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);

     }

 

     /**

      * 精确的除法运算。除不尽时,由scale参数指 定精度 四舍五入。string

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @param scale

      *            表示需要精确到小数点以后几位。

      * @return 两个参数的商

      */

     public static String strDiv(String v1, String v2, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();

     }

   

     /**

      * 精确的除法运算。除不尽时,由scale参数指 定精度 四舍五入。string

      *

      * @param v1

      *            被除数

      * @param v2

      *            除数

      * @param scale

      *            表示需要精确到小数点以后几位。

      * @return 两个参数的商

      */

     public static BigDecimal bigDiv(String v1, String v2, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);

     }

     /**

      * 取余数  string

      * @param v1

      * @param v2

      * @param scale

      * @return

      */

     public static BigDecimal strRemainder(String v1,String v2, int scale){

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);

     }

     /**

      * 取余数  string

      * @param v1

      * @param v2

      * @param scale

      * @return  string

      */

     public static String strRemainder2Str(String v1,String v2, int scale){

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

     }

   

     /**

      * 比较大小 如果v1 大于v2 则 返回true 否则false

      * @param v1

      * @param v2

      * @return

      */

     public static boolean strcompareTo(String v1,String v2){

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         int bj = b1测试数据pareTo(b2);

         boolean res ;

         if(bj>0)

             res = true;

         else

             res = false;

         return res;

     }

   

     /**

      * 比较大小 如果v1 大于等于v2 则 返回true 否则false

      * @param v1

      * @param v2

      * @return

      */

     public static boolean strcompareTo2(String v1,String v2){

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         int bj = b1测试数据pareTo(b2);

         boolean res ;

         if(bj>=0)

             res = true;

         else

             res = false;

         return res;

     }

   

     /**

      * 比较大小 如果v1 等于v2 则 返回true 否则false

      * @param v1

      * @param v2

      * @return

      */

     public static boolean strcompareTo3(String v1,String v2){

         BigDecimal b1 = new BigDecimal(v1);

         BigDecimal b2 = new BigDecimal(v2);

         int bj = b1测试数据pareTo(b2);

         boolean res ;

         if(bj==0)

             res = true;

         else

             res = false;

         return res;

     }

    

     /**

      * 取余数  BigDecimal

      * @param v1

      * @param v2

      * @param scale

      * @return

      */

     public static BigDecimal bigRemainder(BigDecimal v1,BigDecimal v2, int scale){

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);

     }

    

     /**

      * 提供精确的小数位四舍五入处理。

      *

      * @param v

      *            需要四舍五入的数字

      * @param scale

      *            小数点后保留几位

      * @return 四舍五入后的结果

      */

     public static double round(double v, int scale) {

         if (scale < 0) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero");

         }

         BigDecimal b = new BigDecimal(Double.toString(v));

         BigDecimal one = new BigDecimal("1");

         return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

     }

   

     /**

      * 提供精确的小数位四舍五入处理。string

      *

      * @param v

      *            需要四舍五入的数字

      * @param scale

      *            小数点后保留几位

      * @return 四舍五入后的结果

      */

     public static String strRound(String v, int scale) {

         if (scale < 0 ) {

             throw new IllegalArgumentException(

                     "The scale must be a positive integer or zero" );

         }

         BigDecimal b = new BigDecimal(v);

         return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

     }     

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_21063873/article/details/47778113

查看更多关于Java中求Logn/log2 的精度问题的详细内容...

  阅读:15次