做网站需要工商证吗,广平手机网站建设,备案后修改网站名称,广州app软件开发公司为什么浮点类型存在误差
带有小数的表示#xff1a; 25.3 整数通过除2取余法表示#xff1a; 25/2…1 12/2…0 6/2…0 3/2…1 1/2…1 倒过来#xff1a;25#xff08;十进制#xff09; 11001#xff08;二进制#xff09; 小数部分通过乘2取整法#xff1a; 0.3 * 2 …为什么浮点类型存在误差
带有小数的表示 25.3 整数通过除2取余法表示 25/2…1 12/2…0 6/2…0 3/2…1 1/2…1 倒过来25十进制 11001二进制 小数部分通过乘2取整法 0.3 * 2 0.6 …0 0.6 * 21.2…1 0.220.4…0 0.420.8…0 0.821.6…1 0.621.2…1 0.220.4…0 0.420.8…0 0.821.6…1 0.621.2…1 0.220.4…0 0.420.8…0 … 再往下就是0011不断的重复这说明了用二进制表示小数存在不能完全准确表示的情况只能无限的逼近换句话说就是十进制的小数太小了导致一些小数无法用二进制完全准确的表示了只能用近似值表示这就是浮点类型存在误差的原因。 假设有12位的存储空间的话上面只能表示为0.010011001100 换成十进制数就是 02-1 02-112-202-302-412-512-602-702-812-912-1002-110*2-12 01/4001/321/641/5121/1024
0.250.031250.0156250.0019531250.0009765625 0.2998046875 这个数就是浮点数表示的0.3,所以说是由于小数在十进制转化到二进制时存在无法完全转化即存在循环的情况导致了其不能完全准确的用二进制表示十进制数。 这就决定了浮点的小数不能准确的表示根因就是十进制小数存在不能完全转化为二进制小数的问题。 当前也存在可以准确转化的数比如 0.75 0.7521.5…1 0.521.0…1 (0.11)2进制0.75十进制 12-112-2 0.75
在代码当中的情况
程序情况
#include iostream
int main()
{float f1 7.123456789;float f2 7.123456875;std::cout (f1 ! f2 ? f1 f2 not same\n : f1 f2 same\n);float g 1.0 / 3.0;double d 1.0 / 3.0;std::cout (g d ? g d same\n : g d not same\n);double d1 1.9*9;double d2 17.1;std::cout (d1 d2 ? d1 d2 same\n : d1 d2 not same\n);std::cout Hello World!\n; std::string str 8.211267;std::string str2 8.211267;double fC1 9999.25899999;double fC2 9999.25899999;double fA atof(str.c_str())* fC1;double fB atof(str2.c_str())* fC2;if (fA fB){std::cout equal std::endl;}else{std::cout not equal std::endl;}
}运行情况
运行时内存情况
f1与f2为什么不相等呢
首先由于十进制单精度浮点数的有效位数为7两个前7位相等而后面不同的数有可能在计算机中表示为同一个浮点数因而判断两数不等而失败 为了避免这类问题请统一使用double而不要混用不同精度的浮点。对于C来说float已是昔日黄花除了过渡一些C程序在新编的程序中实在没有太大用处因为double完全包含了它 而且浮点运算在内部都是先化为double进行的使用float还必须付出转换回来的时间开销因此混进float只会添乱
d1与d2为什么不相等呢
由于浮点数在计算机内实际上是一个近似表示在手工计算看来为正确的结果在计算机中运算未必能得出正确的结果。 因为浮点数的构成原理决定了十进制数在转换为内部浮点数时由无穷尾数而带来的不精确性。上面程序中d1和d2变量的值本应相等却在计算机内部为不等。 1.9我们看着是1.9实际内存存储的可不是1.9啊是什么呢如下所示
呵呵竟然是1.89999999999…
总结
所以我们还得到另外一个重要的经验使用浮点数进行相等和不等比较的操作通常是有问题的。浮点数的相等比较 一般总是使用两者相减的值是否落在0的邻域中来判断的。 d1,d2如果这样比就会相等:
简单的说就是浮点类型的数存在误差通过两个数的差是否落在0的邻域进行判断即可