| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1625 人关注过本帖
标题:一个神奇的问题和它的答案
只看楼主 加入收藏
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:7 
我也测试了

0x80000000
0x80000080
...


[fly]存在即是合理[/fly]
2013-11-27 22:14
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 8楼 beyondyf
我也奇怪着,课堂上有人在ubuntu下测试对于某些大于2^24次方的数是不会输出TRUE的,但我回来用VC测试好像全都会输出,好迷惑- -

好吧,我公布一下答案,因为float采用24位存储尾数,所以对于在二进制下大于24位且最后几位不全为零的时候会因为编译器在化整数为1.a*2^b时a末尾存在的1省略掉而构成精度误差,但是现在测试不出来了= =

我也不知道为什么。可能编译器有什么特殊的处理不知道。。
2013-11-27 22:15
Susake
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:女儿国的隔壁
等 级:贵宾
威 望:23
帖 子:2288
专家分:6481
注 册:2012-12-14
收藏
得分:7 
自己的编译器行,但是LZ这么问!
大胆猜测下:与编译器有关!

仰望星空...........不忘初心!
2013-11-27 22:27
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
vs2012,有精度丢失
程序代码:
#include <stdio.h>
#include <limits.h>

int main()
{
    for (int n = INT_MIN; n < INT_MAX; n++)
    {
        if (n == (int)(float)n)
        {
            printf_s("0x%p\n", n);
            getchar();
        }
    }
}


[fly]存在即是合理[/fly]
2013-11-27 22:28
a151141
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:197
专家分:680
注 册:2012-10-19
收藏
得分:0 
回复 8楼 beyondyf
不知道版主如何实际测试了32位的所有数据?

世界上幸福的事就是抓到一只羊,更幸福的事就是抓到两只羊……
2013-11-27 22:41
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
哦,你用下面的代码就能实验成功了。
int n;
float f;
f = n;
if(n == (int)f) printf("TRUE");

我在印象中依稀记得IEEE对浮点运算的中间变量也有规定,精度远高于存储类型(好像是80位,不确定,也不想查了)。

如果确实如此,那么(float)n转换的结果是存储在一个中间临时变量中,再到int的转换又是从这个中间临时变量来的,其精度足矣满足32位整型的要求。

上面代码增加一个float变量就是为了消除临时中间变量精度的影响。

重剑无锋,大巧不工
2013-11-27 22:42
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 16楼 beyondyf
原来是这样,中间变量还有专门的规定啊。。
2013-11-27 22:47
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
呵呵,还是查了一下,x86的浮点运算单元是80位的,我说怎么记住这么个数。而具体如何存储还是和编译器有关的。

重剑无锋,大巧不工
2013-11-27 22:57
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 15楼 a151141
程序代码:
#include<stdio.h>
int main()
{
    int n;
    for(n = 1; n; n++)
    {
        if(!(n & 0xFFFFFF)) printf("%d\n", n);
        if(n != (int)(float)n)
        {
            printf("n = %d\n", n);
            break;
        }
    }
    return 0;
}

这就是我测试用的代码。

if(!(n & 0xFFFFFF)) printf("%d\n", n);这句仅仅是为了观察当前计算到哪里了而已。

关键是要看printf("n = %d\n", n);这句是否输出。

重剑无锋,大巧不工
2013-11-27 23:01
cosdos
Rank: 9Rank: 9Rank: 9
来 自:ShangHai
等 级:蜘蛛侠
威 望:6
帖 子:2109
专家分:1385
注 册:2007-6-19
收藏
得分:0 
回复 12楼 czz5242199
被编译器优化了,(int)(float)无意义。

—>〉Sun〈<—
2013-11-27 23:02
快速回复:一个神奇的问题和它的答案
数据加载中...
 
   



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

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