为什么double转float不会出现数据误差,而float转double却误差如此之大?double d = 3.14;float f = (float)d;System.out.println(f);输出结果是:3.14; float f = 127.1f;double d = f;System.out.println(d);输出结果是:127.0999984741211 为什么结果会是这样呢?如何避免这样的问题发生,让float转double能得到实际的数据?
解决方案 »
- 字符串分割怎么把分割符也保留了
- 关于Java输入流的问题
- Socket 问题,很头痛
- 关于gridlayout布局的问题````
- JInternalFrame的右上角的关闭按钮点击后,实现了什么?
- java的方法能不能传递过程(或者方法名、函数名)参数???
- 有没有办法设置Connection永远不会超时?
- 小菜鸟的问题:用jdk的java可以解释执行出一个窗体么???我的例子:
- 强烈推荐:很多好书,包括中文版的《thinking in java》,下载速度暴快!!
- 电气专业刚转软件编程,自学JAVA中遇到了问题,求前辈帮忙看看
- JAVA控制台能每输入一个字符反馈一下吗?
- 各位大牛问帮帮给解决一下
具体代码没有去实现了,这样应该可以。
是属于强制转换,会丢失精度的
float f = 127.1f;
BigDecimal b = new BigDecimal(String.valueOf(f));
double d = b.doubleValue();
System.out.println(d);
你可以试下这段代码本来都不精确+1
* 提供精確的加法運算
* @param args
*/
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 args
*/
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 args
*/
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();
}
/**
* 提供了(相對)精確的除法運算,當發生除不儘的情況時,精確到
* 小數點以後110位
* @param args
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供了(相對)精確的除法運算,當發生除不儘的情況時,由scale參數指定
* 精度,以後的數字四捨五入
* @param args
*/
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();
}
/**
* 提供了精確的小數位四捨五入處理
* @param args
*/
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_DOWN).doubleValue();
}
public static void main(String[] args) {
System.out.println(add(1.2321231, 3.7865765));
System.out.println(sub(6.4523423, 1.2321231));
System.out.println(mul(6.4523423, 3.7865765));
System.out.println(div(6.4523423, 3.7865765, 5));
System.out.println(round(3.7865765, 5));
}
}
JAVA中float为四个字节,double为八个字节,float--->double时候会补位,如果这里补位不出现误差的话应该可以实现。你先将float类型数据包装成BigDecimal数据,然后调用其floatValue()方法可以实现。
坐等达人出现了~~我觉得BigDecimal类应该可以实现的,你可以去查一下api
弄反了吧,double to float才是强制转换,float--->double转换会扩充精度的,float的精度可能为0.0000001,而double的精度可能为0.0000000000001这样转换后可能会有0.0000001 - 0.0000000000001(~=0.0000001)的误差
BigDecimal b = new BigDecimal(Float.toString(f));
double d = b.doubleValue();
System.out.println(d);---------这样可以不丢失精度--------
之所以那样是因为float为四个字节,double为八个字节
转化为double时 被扩展了
你想想 原来小数点后只有7位精度 现在要变成16位 是被扩展了 而不是误差
double d = f;
ystem.out.println(d);
输出结果是:127.0999984741211
double向float转换时,是强制类型转换~有8个字节强制变4个字节~那它就强制丢弃后4个字节,你就是强制丢失精度,所以不会出现小数点很多的情况 double d = 3.14; float f = (float)d; System.out.println(f); 输出结果是:3.14;
由此看来基础真的是太重要啦
不知道我分析的对不对~初学,希望给位多加指正
public static double toDouble(float f) {
String s = f+"";
if (s != null && !"".equals(s.trim())) {
return Double.parseDouble(s);
}
return 0;
}