Java中float和double转换的问题?

sea2010seadesdsf 2010-08-02 02:00:13
为什么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能得到实际的数据?
...全文
36607 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaodick 2012-04-12
  • 打赏
  • 举报
回复
这样可以的:
public static double toDouble(float f) {
String s = f+"";
if (s != null && !"".equals(s.trim())) {
return Double.parseDouble(s);
}
return 0;
}
rongkaixuan 2012-01-20
  • 打赏
  • 举报
回复
我试验发现其实这就是个简单的类型转换问题同一个数~float可以向double自动提升,由原来的4个字节变8个字节产生类位数扩展,所以出现精度问题,其实是自动补位造成的~~float f = 127.1f;
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;
由此看来基础真的是太重要啦
不知道我分析的对不对~初学,希望给位多加指正
恬毅 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 sea2010seadesdsf 的回复:]
为什么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(……
[/Quote]+1
msfx1214 2010-08-05
  • 打赏
  • 举报
回复
JAVA中double类型float类型计算都会有精度差,所以推荐使用BigDecimal
coooliang 2010-08-04
  • 打赏
  • 举报
回复
[Quote=引用楼主 sea2010seadesdsf 的回复:]
为什么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(……
[/Quote]
不是误差 float转double是合法转换
之所以那样是因为float为四个字节,double为八个字节
转化为double时 被扩展了
你想想 原来小数点后只有7位精度 现在要变成16位 是被扩展了 而不是误差
littleJP 2010-08-03
  • 打赏
  • 举报
回复
先把float型的变成String类型的,然后再装换成Double的
e9876 2010-08-03
  • 打赏
  • 举报
回复
Double.parseDouble(127.1f+"");
t181935471 2010-08-03
  • 打赏
  • 举报
回复
double转float肯定会丢失精度,只不过你现在转换的值的位数满足float的位数要求而已

这些基础问题自己google解决问题啊
lizhongyi188 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 natalya13 的回复:]

引用 6 楼 liuchenyu 的回复:
float--->double
是属于强制转换,会丢失精度的


弄反了吧,double to float才是强制转换,

float--->double转换会扩充精度的,float的精度可能为0.0000001,而double的精度可能为0.0000000000001这样转换后可能会有0.0000001 - 0.000000000000……
[/Quote]
+1
高亮 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 liuchenyu 的回复:]
float--->double
是属于强制转换,会丢失精度的
[/Quote]

弄反了吧,double to float才是强制转换,

float--->double转换会扩充精度的,float的精度可能为0.0000001,而double的精度可能为0.0000000000001这样转换后可能会有0.0000001 - 0.0000000000001(~=0.0000001)的误差
avalon 2010-08-02
  • 打赏
  • 举报
回复
我也没有测试过,晚上因为太晚了,float-->double要补位,还真不知道精确不,如果是要得到精确double进行计算,BigDecimal包装double数据,然后计算,最后调用其doubleValue()就容易实现。。
坐等达人出现了~~我觉得BigDecimal类应该可以实现的,你可以去查一下api
dream1889 2010-08-02
  • 打赏
  • 举报
回复
学习中。。
龙四 2010-08-02
  • 打赏
  • 举报
回复
所以说看书还是很重要的

大学里 计算机文化基础 之类的课程里应该对补码原码讲的很清楚
donghua123 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhuzeitou 的回复:]
引用 3 楼 rzhft 的回复:

1楼BigDecimal的方法不可行好像



Java code
float f = 127.1f;
BigDecimal b = new BigDecimal(String.valueOf(f));
double d = b.doubleValue();
System.out.println(d);

你可以试下这段代码

本来……
[/Quote]


这个很详细,我在进行金额操作的时候 都这种方法,避免出错。。。
fgtljx 2010-08-02
  • 打赏
  • 举报
回复
学到了些东西啊~~~
凉岑玉 2010-08-02
  • 打赏
  • 举报
回复
是因为doble比float更精确的缘故··
jeffrey281 2010-08-02
  • 打赏
  • 举报
回复
/**
* 提供精確的加法運算
* @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()方法可以实现。

zhuzeitou 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 rzhft 的回复:]

1楼BigDecimal的方法不可行好像
[/Quote]

float f = 127.1f;
BigDecimal b = new BigDecimal(String.valueOf(f));
double d = b.doubleValue();
System.out.println(d);

你可以试下这段代码

本来都不精确+1
liuchenyu 2010-08-02
  • 打赏
  • 举报
回复
float--->double
是属于强制转换,会丢失精度的
ZangXT 2010-08-02
  • 打赏
  • 举报
回复
本来都不精确
加载更多回复(6)

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧