| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 505 人关注过本帖
标题:long 的精度问题
只看楼主 加入收藏
换空依晨
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2013-9-13
结帖率:30.77%
收藏
已结贴  问题点数:10 回复次数:4 
long 的精度问题
// fltadd.cpp -- precision problems with float
#include <iostream>
int main()
{
    using namespace std;


    long double a = 2.34E+22;
   long double  b = a + 1.0;

    cout << "a = " << a << endl;
    cout << "b - a = " << b - a << endl;
    return 0;
}
为什么b-a不等于1,

[ 本帖最后由 换空依晨 于 2014-3-20 09:55 编辑 ]
搜索更多相关主题的帖子: problems include double 
2014-03-20 09:52
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54061
注 册:2011-1-18
收藏
得分:10 
long a = 2.34E+22; 已经溢出了,按照C/C++标准,其行为是未定义的。
了解什么是“未定义行为”,就不需要问为什么了,因为未定义行为没有为什么。

--------------- 以下不是给你看的 ---------------
为什么某些编译器下 b - a 为 0 ?
答:这是因为带符号整型的溢出属于未定义行为,因此编译器不考虑带符号整型的溢出可能。(能理解这个逻辑吧)
2.34E+22 + 1.0 等于 2.34E+22 (能看懂吧)
因此,编译器可以直接将上述代码优化为:
    long a = 2.34E+22;
    long b = 2.34E+22;
    cout << "a = " << a << endl;
    cout << "b - a = " << b - a << endl;
再优化为
    cout << "a = " << ??? << endl;
    cout << "b - a = " << 0 << endl;

2014-03-20 10:11
换空依晨
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2013-9-13
收藏
得分:0 
回复 2楼 rjsp
long double 的精度有16个字节 吧 2^16
2014-03-20 21:43
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54061
注 册:2011-1-18
收藏
得分:0 
回复 3楼 换空依晨
晕,你改代码了,我记得原来写的是 long,而不是 long double。

“long double 的精度有16个字节 吧 2^16 ”
 ------ 这都是哪些家伙瞎说的呀?!我已经晕了,平静的讲:
首先,C/C++没有规定long double占多少位,只要不比double少就行。原话是:
The set of values of the type float is a subset of the set of values of the type double;
the set of values of the type double is a subset of the set of values of the type long double.
其次,long double 参照来源于80387 FPU中的80bits临时实数类型,也就是编译器一般将long double设为10字节。
之所以说“一般”,是因为上面已经讲过,C/C++标准没有做任何强制规定。比如 VC++5.0之后,VC的long double其实只有8bytes,和double是一样的;gcc的long double占12bytes,虽然起作用的只有10bytes。

其次,即使“long double 的精度有16个字节”,那也应该是小于 2^(16*8) 呀,2^16等于65536你知道不?
另外,即便是16个字节,那也只代表其『最多』能表达出2^(16*8)个不同的数值,何其取值范围是无关的。

最后,我不知道你说的“精度”指什么鸟玩意儿,猜吧
float的尾数有23bits,及1个隐藏位,因此 log(2^24)=7.22,所以有人说float有效位数是7个
double的尾数有52bits,及1个隐藏位,因此 log(2^53)=15.95,所以有人说double有效位数是16个
long double的尾数有64bits,无隐藏位,因此 log(2^64)=19.26,所以有人说long double有效位数是19个

2014-03-21 09:11
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54061
注 册:2011-1-18
收藏
得分:0 
根据以上讲述后,long double即使有80bits,那也只有19个有效数字
也就是 2.34E+22 + 1.0 还是 2.34E+22,除非你用能有23个有效数字的类型
2014-03-21 09:15
快速回复:long 的精度问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033416 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved