首页 > 其他分享 >浮点数引起的错误

浮点数引起的错误

时间:2023-05-15 23:44:47浏览次数:43  
标签:std 错误 0.1 double 浮点数 int d2 引起

一、浮点数精度

Float 为单精度,内存中占 4 个字节,有效数位是 7 位。

double为 双精度,占 8 个字节,有效数位是 16 位。

 

二、常见错误

1. 不能存储全部有效数字

#include <iostream>

int main()
{
    float f{ 0.123456789f };
    std::cout << f << '\n';

    return 0;
}

打印:0.123457

 

2. 采用比较运算符时

#include <iostream>

int main()
{
    double d1{ 100.0 - 99.99 }; // should equal 0.01 mathematically
    double d2{ 10.0 - 9.99 }; // should equal 0.01 mathematically

    if (d1 == d2)
        std::cout << "d1 == d2" << '\n';
    else if (d1 > d2)
        std::cout << "d1 > d2" << '\n';
    else if (d1 < d2)
        std::cout << "d1 < d2" << '\n';

    return 0;
}

d1和d2理应一致,但是打印结果为:d1 > d2

如果用Debugger来看,d1 = 0.0100000000000005116 ,d2 = 0.0099999999999997868,这导致了出现了意料之外的结果。

通常来说,用比较运算符是对的,但是当用于比较的两个数非常接近时,可能出现错误。

 

3. 使用==和!=时

注意!一定不要在比较浮点数时使用==,因为只有当两个数完全一模一样是,才会返回true,否则即使最小的舍入误差都会导致结果为false。

看以下错误出现的例子:

#include <iostream>

int main()
{
    double d{ 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 }; // should sum to 1.0

    if (d == 1.0)
        std::cout << "equal\n";
    else
        std::cout << "not equal\n";

    return 0;
}

 

打印结果是:not equal

 

所以,我们可以用下面这个代码来替代==,

#include <cmath> // for std::abs()

// epsilon is an absolute value
bool approximatelyEqualAbs(double a, double b, double absEpsilon)
{
    // if the distance between a and b is less than absEpsilon, then a and b are "close enough"
    return std::abs(a - b) <= absEpsilon;
}

 

还有一些更严谨的方法,但是实现复杂度也更高,具体查看该网页拓展部分:https://www.learncpp.com/cpp-tutorial/relational-operators-and-floating-point-comparisons/  

 

4. 整数除法

我们对两个整数做除法操作,我们想要的是一个浮点数,但是得到的确会是一个整数。

#include <iostream>

int main()
{
    int x{ 5 };
    int y{ 3 };

    std::cout << x << " divided by " << y << " is: " << x / y << '\n'; // integer division

    return 0;
}

 打印结果为:5 divided by 3 is: 1

我么可以用static_cast函数将其中一个整数转为浮点数,最后得到的结果就是浮点数。或者写成5.0/7.0。

标签:std,错误,0.1,double,浮点数,int,d2,引起
From: https://www.cnblogs.com/spacerunnerZ/p/17403485.html

相关文章

  • '\t'引起的bug导致if语句失效
    用了多半天的时间终于领教了这个'\t'的厉害,今天的代码中一个if语句总是不起作用,怎么找怎么改,都无效,最后终于发现原来if条件里的字符串需要首尾加上'\t',才能和数据匹配上,因为我的数组是用EXCEL制作,直接拷过来的,表面上是看不见制表符'\t'的,多亏我从控制台打印了一下数组,......
  • 3、zookeeper的选举----经验证符合事实,网上很多都是错误的
    目录Zookeeper系列文章目录一、概念1、Zookeeper节点状态2、事务ID二、集群初始化选举1、每个Server发出一个投票2、接受来自各个服务器的投票3、处理投票4、统计投票5、改变服务器状态三、集群重新选举1、变更状态2、每个Server会发出一个投票3、接收来自各个服务器的投票4、处......
  • minikube提示找不到“Features.Enable-SwaggerUI”flag错误
    安装minikube之后想要开启apiswagger,发现报如下错误:❌在kube-apiserver[1346b5005eae]中检测到问题:Error:unknownflag:--Features.Enable-SwaggerUI查资料发现是k8s中已经移除了api的swagger,想要查看api的swagger文档需要自己启动swaggerui服务(请自行搜索)。但......
  • 错误cphs解决方法
    该方法不通用,但确实的解决了我的问题 问题描述:windows10日志cphs服务报错或Intel(R)ContentProtectionHECIService服务因下列错误而停止:未指定的错误解决方 解决方法: (1)首先建议执行一下干净启动,排除其他干扰:https://support.microsoft.com/zh-cn/help/929135........
  • linux标准输入/输出/错误及重定向
    标准输入/输出/错误linux下每个进程在运行的过程中都会打开一系列的文件,可以通过lsof-p$pid来查看进程号为pid打开的文件,在/proc/pid/fd/下是该进程打开的文件的链接。其中有三个比较特殊的文件是每个进程都会打开,其文件描述符分为0,1,2,默认分别链接到标准输入(STDIN_FILENO)设备......
  • 系统错误:找不到mvcp120d.dll,无法继续执行代码
    0、问题出现小背景:安装mysql,在初始化:mysqld--initialize--console发现直接没有显示密码,也没有报错在cmd窗口下,输入命令行:mysqldinstall,[前提:windows系统已经配置了mysql环境],回车键,就看到提示信息:找不到mvcp120d.dll,无法继续执行代码1、找不到mvcp120d.dll,无法继续执行......
  • git commit错误 error: bad signature 0x00000000 fatal: index file corrupt
    gitcommit错误error:badsignature0x00000000fatal:indexfilecorrupt 这个错误信息表明您的git仓库中的索引文件已损坏。修复此问题的一种方法是删除索引文件并重置它。您可以在仓库的根目录中运行以下命令:rm-f.git/indexgitreset这将删除索引文件并将其还原......
  • AntDesign的Form表单内容有值但是仍然报请输入的错误
    案例解决方案a-form标签上有:model="formState"a-form-item中的name值和v-model:value对应值保持一致案例<a-form:label-col="labelCol":wrapper-col="wrapperCol"ref="formRef":model="formState">......
  • spring遇到的几个错误(5.14)
     先保存配置文件file→ProjectStructure→Modules 详细问题 ......
  • C#使用Snap7读写西门子全糸列PLC,非常方便,通信稳定可靠,是C#上位机工程师的通讯利器,布尔
    C#使用Snap7读写西门子全糸列PLC,非常方便,通信稳定可靠,是C#上位机工程师的通讯利器,布尔字符浮点数整数字节都可读写ID:59100676026758780......