原因可能是最近看的一部電影讓我頗憂鬱
《明天,我要和昨天的妳約會》
不說了,進正題吧QuQ
這次作業是讓我們用Babylonian method來求正數平方根並四捨五入到小數點後第二位
演算法不難照公式打就好
我覺得難的是四捨五入 (突然想到高中zero judge的d561:被秒殺的四捨五入
所以本篇主要記錄我查到的各種四捨五入方法
以下程式我改寫成能夠自訂位數
public static double round(double value, int places){} //value為想四捨五入的數、places為取到小數點下第幾位
一、Math.round
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rounding; | |
public class RoundByMathRound { | |
public static double round(double value, int places) { | |
if (places < 0) throw new IllegalArgumentException(); | |
long factor = (long) Math.pow(10, places); | |
value = value * factor; | |
long tmp = Math.round(value); | |
return (double) tmp / factor; | |
} | |
} |
二、DecimalFormat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rounding; | |
import java.text.DecimalFormat; | |
public class RoundByDecimalFormat { | |
public static double round(double value, int places) { | |
if (places < 0) throw new IllegalArgumentException(); | |
String format = "#."; | |
for(int i = 0; i < places; i++){ | |
format+="#"; | |
} | |
DecimalFormat df = new DecimalFormat(format); | |
return Double.parseDouble(df.format(value)); | |
} | |
} |
三、BigDecimal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rounding; | |
import java.math.BigDecimal; | |
import java.math.RoundingMode; | |
public class RoundbyBigDecimal { | |
public static double round(double value, int places) { | |
if (places < 0) throw new IllegalArgumentException(); | |
BigDecimal bd = new BigDecimal(value); | |
bd = bd.setScale(places, RoundingMode.HALF_UP); | |
return bd.doubleValue(); | |
} | |
} |
四、自幹一個字串處理 (會有bugs,踩雷記錄QuQ)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rounding; | |
public class RoundByStringHandling { | |
public static double round(double value, int places){ | |
if (places < 0) throw new IllegalArgumentException(); | |
StringBuilder sb = new StringBuilder(((Double)(value)).toString()); | |
StringBuilder resultString = null; | |
double resultValue = 0D; | |
boolean isFindDot = false; | |
String avoidOverIndexZero = ""; | |
for(int i = 0; i < places; i++){ | |
avoidOverIndexZero += "0"; | |
} | |
for(int i = 0; i < sb.length(); i++){ | |
if(sb.charAt(i) == '.'){ | |
isFindDot = true; | |
sb = sb.append(avoidOverIndexZero);//if value only 1 or 2 decimal add "00" can avoid StringIndexOutOfBoundsException | |
resultString = new StringBuilder(sb.substring(0, i + places + 2));//.toString();//Cut after 3 decimal String | |
break; | |
} | |
} | |
if(isFindDot == false){//no dot represent value is integer | |
return value; | |
} | |
else{ | |
int nextDecimal = Integer.parseInt(resultString.substring(resultString.length()-1)); | |
//System.out.println(nextDecimal); | |
if(nextDecimal >= 5){ | |
resultString.deleteCharAt(resultString.length()-1); | |
resultValue = Double.parseDouble(resultString.toString())+Math.pow(0.1, places); | |
} | |
else{ | |
resultString.deleteCharAt(resultString.length()-1); | |
resultValue = Double.parseDouble(resultString.toString()); | |
} | |
} | |
return resultValue; | |
} | |
} |
實際測試:(精確度都以2位為測試)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rounding; | |
import java.util.Scanner; | |
public class RoundingTest { | |
public static void main(String[] args) { | |
Scanner scanner = new Scanner(System.in); | |
double num = Double.parseDouble(scanner.nextLine()); | |
System.out.println("Origin:\t"+(num)); | |
double d1 = RoundByMathRound.round(num, 2); | |
System.out.println("d1:\t" + d1); | |
double d2 = RoundByDecimalFormat.round(num, 2); | |
System.out.println("d2:\t" + d2); | |
double d3 = RoundbyBigDecimal.round(num, 2); | |
System.out.println("d3:\t" + d3); | |
double d4 = RoundByStringHandling.round(num, 2); | |
System.out.println("d4:\t" + d4); | |
scanner.close(); | |
} | |
} |
結果:
驚人發現在2.345時用字串處理會錯誤,原因應該是某東方神秘力量吧QuQ
參考資料:
Round a double to 2 decimal places [duplicate]