“帶下劃線內(nèi)容無效"
兩種不同方法的實(shí)現(xiàn):
1:
/**
* 提供小數(shù)位四舍五入處理。
* @param v 需要四舍五入的數(shù)字
* @param scale 小數(shù)點(diǎn)后保留幾位
* @return 四舍五入后的結(jié)果
*/
public static double round(double v,int scale){
String temp="#,##0.";
for (int i=0;i<scale ;i++ )
{
temp+="0";
}
return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
}
2:數(shù)學(xué)方法
public static double round2(double d, int scale) {
long temp=1;
for (int i=scale; i>;0; i--) {
temp*=10;
}
d*=temp;
long dl=Math.round(d);
return (double)(dl)/temp;
}
鑒于網(wǎng)友的的指出,我重新認(rèn)真研究了一下四舍五入,最終給出正確解法如下:
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* 本例通過對(duì)網(wǎng)上幾種取四舍五入的研究,進(jìn)行了一一測(cè)試。最終通過實(shí)驗(yàn)和理論得出round4為唯一正確的算法。
* 2008/10/13
*
* @author jamezhan
*
*/
public class RoundTest {
public static double round1(double v, int scale) {
if (scale < 0)
return v;
String temp = "#####0.";
for (int i = 0; i < scale; i++) {
temp += "0";
}
return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
}
/**
* 該算法會(huì)出現(xiàn)中間運(yùn)算后結(jié)果超過Double.MAX_VALUE,所以不推薦使用
* @param d
* @param scale
* @return
* @throws Exception
*/
public static double round2(double d, int scale) throws Exception {
if (scale < 0)
return d;
long temp = 1;
for (int i = scale; i > 0; i--) {
temp *= 10;
}
if (Math.abs(d * temp) > Double.MAX_VALUE)
throw new Exception("data is too big or too small");
d *= temp;
long dl = Math.round(d);
return (double) (dl) / temp;
}
public static double round3(double v, int scale) {
BigDecimal value = new BigDecimal(v);
float actualTax = value.setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
return actualTax;
}
public static double round4(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();
}
public static void testRound1(double d, int scale) {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round1(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
}
public static void testRound2(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round2(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void testRound3(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round3(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void testRound4(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round4(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void main(String[] args) throws Exception {
System.out.println("****************************** Test round1 ******************************");
testRound1(Double.MAX_VALUE,2);
testRound1(1.264,2);
testRound1(-1.264,2);
testRound1(1.265,2);//wrong result
testRound1(-1.265,2);//wrong result
testRound1(1.266,2);
testRound1(-1.266,2);
testRound1(10224948.265,2);//wrong result
testRound1(-10224948.265,2);//wrong result
testRound1(-Double.MAX_VALUE, 2);
System.out.println("****************************** Test round2 ******************************");
testRound2(Double.MAX_VALUE,2);
testRound2(1.264,2);
testRound2(-1.264,2);
testRound2(1.265,2);//wrong result (java表示小數(shù)0.1的問題導(dǎo)致的 1.265表示為1.2599999904632568)
testRound2(-1.265,2);//wrong result (由于round算法是先加0.5再運(yùn)算,所以d為負(fù)數(shù)時(shí)且最后一位小數(shù)為5時(shí)結(jié)果是不正確的)
testRound2(1.266,2);
testRound2(-1.266,2);
testRound2(10224948.265,2);
testRound2(-10224948.265,2);//wrong result
testRound2(-Double.MAX_VALUE, 2);
System.out.println("****************************** Test round3 ******************************");
testRound3(Double.MAX_VALUE,2);//wrong result
testRound3(1.264,2);
testRound3(-1.264,2);
testRound3(1.265,2);
testRound3(-1.265,2);
testRound3(1.266,2);
testRound3(-1.266,2);
testRound3(10224948.265,2);//wrong result
testRound3(-10224948.265,2);//wrong result
testRound3(-Double.MAX_VALUE, 2);//wrong result
System.out.println("****************************** Test round4 ******************************");
testRound4(Double.MAX_VALUE,2);
testRound4(1.264,2);
testRound4(-1.264,2);
testRound4(1.265,2);
testRound4(-1.265,2);
testRound4(1.266,2);
testRound4(-1.266,2);
testRound4(10224948.265,2);
testRound4(-10224948.265,2);
testRound4(-Double.MAX_VALUE, 2);
}
}