日期:2014-05-20  浏览次数:20656 次

453*0.8=362.40000000000003???关于超市打折问题的疑惑
import java.text.DecimalFormat;//调用类库
/*实付金额与消费金额问题:<100全款,100-<200 95折,200-<300 9折,300-<400 85折,400-<500 8折,500-<75折.
 * 请分别用switch语句和if语句两种形式实现该功能*/
import java.util.Scanner;
 



public class Actualpayments {


public static void main(String[] args) {

// TODO Auto-generated method stub
int money ;
System.out.println("Please input the money:");
// DecimalFormat df =new DecimalFormat("#####0.00");//设置输出结果的小数点位数为两位
 
Scanner sc=new Scanner(System.in);
money = sc.nextInt();
switch(money/100)//money/100表对结果取整
{
case 5:
// System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money*0.75)+"元");
break; 
case 4:
System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+money*0.80+"元");
break; 
case 3:
//System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money*0.85)+"元");
break; 
case 2:
//System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money*0.90)+"元");
break; 
case 1:
//System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money*0.95)+"元");
break; 
case 0:
   //System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money)+"元");
   break; 
//default:System.out.println("你一共消费了"+money+"元,"+"实付金额应为"+df.format(money*0.75)+"元");
  // break; 
}}
}
看了答案仔细心算了下,再用在线计算器计算了下,都是362.4。可我用java编的计算器计算,结果和运行出的结果一样,是362.40000000000003。后来我又试了下几个400多的数字,有部分是正确的输出,也有部分如453一样,后面多了个0.0000....3,。这究竟是怎么回事?为了免于被认为是错误的程序,最后我用DecimalFormat保留两位ie小数点输出。但我一直搞不懂为什么会是这种情况,哪位大神能解释下,为什么会是这样的结果?
------解决方案--------------------
对精度有要求的请用BigDecimal,特别是计算金额的时候
------解决方案--------------------
b1.doubleValue()能运行吗?

b1是int类型的变量;
还有,
System.out.println("你一共消费了"+b1+"元,"+"实付金额应为"+b1.doubleValue()+"元");
放到最后的break里面去;
------解决方案--------------------
double本来就不是十分精确的。这是计算机内部的问题,涉及到金钱的时候一般使用BigDecimal解决
------解决方案--------------------
像用十进制数不能精确表示 1/3 (三分之一)一样,

由于电脑内部处理数据时,都是用的二进制数,很多double型的数据只能用近似数据表示