为什么说“浮点数不可以比较大小”?(浅解)

先来简单地看一段非常简单的代码

#include<iostream>
using namespace std;

int main(){
    double a = 2.01;
    int b = a *100;
    if(b == 201) printf("yes");
    else printf("no, b = %d", b);

    return 0;
}

 输出结果为: no, b = 200

 这就很奇怪,按照一般想法 2.01*100 == 201 这是毋庸置疑的,哪里出bug了呢?

        这牵扯到浮点数的定义问题。首先,我们知道计算机都是用二进制来存储数据的,一个十进制的数比如 11 ,在二进制中可以表示为 1011,用科学计数法表示为 1 x 2^3  +  0 x 2^2  +  1 x 2^1  +  1 x 2^0 ,使用的转换方法是将十进制的数不断取奇为1除以2(不严谨,主要是这里不必多赘述)。同理十进制小数0.25 用二进制表示为 0.01 ,科学计数法表示 0 x 2^-1  +  1 x 2^-2,转换方法是将十进制的数不断乘2取1,比如0.725 x 2 = 1.25,大于1,于是取1,二进制小数点后一位为1;0.25 x 2 = 0.5,整数不足1,二进制小数点后第两位为0; 接着0.5 x 2 = 1,取1后没有余数结束运算,最后结果为0.101。

        根据十进制小数在二进制中的表示,我们可以计算出十进制0.1在二进制中的表示为0.0001100110011...是循环小数,从第二位小数开始不断循环0011。所以想要用限位数的二进制来表示十进制0.1便只能取近值,所以浮点数不可能完全无误精确地表示十进制0.1。

32位浮点数表示0.1 : 0-01111011-10011001100110011001100

转换为十进制数:0.09999999403953552

综上所述,用浮点数来比较大小是不太可靠的。

最后写个代码验证一下

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
    double a = 2.1;
    double b = 0.5;

    int c = a *100;
    int d = b *100;
    if(c == 210) printf("c yes\n");
    if(d == 50 ) printf("d yes\n");//0.5可以准确用二进制表示出来

    printf("c = %d\n", c);
    printf("d = %d\n", d);

    return 0;
}

输出结果:

d yes

c = 209

d = 50

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值