繁体   English   中英

C ++浮点除法和精度

[英]C++ Float Division and Precision

我知道511除以512实际上等于0.998046875。 我也知道浮子的精度是7位数。 我的问题是,当我用C ++(GCC)进行数学运算时,得到的结果是0.998047,这是一个舍入值。 我更喜欢得到截断值0.998046,我该怎么做?

  float a = 511.0f;
  float b = 512.0f;
  float c = a / b;

嗯,这是一个问题。 作为float511/512的值是精确的。 没有舍入。 您可以通过要求超过七位数来检查:

#include <stdio.h>
int main(int argc, char *argv[])
{
    float x = 511.0f, y = 512.0f;
    printf("%.15f\n", x/y);
    return 0;
}

输出:

0.998046875000000

float不是十进制数,而是二进制数。 如果将数字除以2的幂,例如512,则结果几乎总是精确的。 发生了什么是float的精度不仅仅是7位数,它实际上是23 精度。

看看每个计算机科学家应该知道的关于浮点运算的内容

我也知道浮子的精度是7位数。

不是。最常见的浮点格式是二进制格式,精度为24位。 它介于6到7位十进制数字之间,但如果您想了解舍入工作的方式,则无法用十进制表示。

由于b是2的幂,c是完全可表示的。 在十进制表示转换期间,将发生舍入。 获取十进制表示的标准方法不提供使用截断而不是舍入的可能性。 一种方法是要求多一个数字并忽略它。

但请注意,c完全可表示的事实是其值的属性。 SOme显然更简单(如0.1)没有二进制FP格式的精确表示。

通过某种输出方法而不是实际存储的内容,“圆润”值最有可能显示出来。 检查调试器中的实际值。

使用iostream和stdio,您可以指定输出的精度。 如果指定7位有效数字,将其转换为字符串,然后在显示之前截断字符串,您将获得输出而不进行舍入。

想不出你想要这样做的一个原因,并且考虑到应用程序的后续解释,你最好使用双精度,尽管这很可能只是将问题转移到其他地方。

你的问题并不是独一无二的,之前已经多次回答。 这不是一个简单的主题,只是因为发布答案并不一定意味着他们的质量会很好。 如果你浏览一下,你会发现真正好的东西。 它会花费你更少的时间。

我敢打赌有人会对我进行评论而不回答。

_____编辑_____

理解浮点的基础是要意识到一切都以二进制数字显示。 因为大多数人都难以理解这一点,所以他们试图从小数位的角度来看待它。

关于511/512的主题,您可以从值1.0开始。 在浮点数,这可以表示为i.000000 ... * 2 ^ 0或隐含位设置(到1)乘以2 ^ 0即等于1.由于511/512小于1,您需要从下一个开始低功率-1给出i.000000 ... * 2 ^ -1即0.5。 请注意,唯一改变的是指数。 如果我们想用二进制表示511,我们得到9个--111111111或浮点与隐式位i.11111111 - 我们可以除以512并将指数放在-1给i.1111111100 ... * 2 ^ -1。

这怎么转化为0.998046875?

那么从隐式位开始表示0.5(或2 ^ -1),第一个显式位0.25(2 ^ -2),下一个显式位0.125(2 ^ -3),0.0625,0.03125等等,直到你' ve代表第九位(第八位显式)。 总结一下,得到0.998046875。 从i.11111111我们发现这个数字代表精度的9位二进制数字,巧合的是9位小数精度。

如果您将511/512乘以512,您将获得i1111111100 ...... * 2 ^ 8。 这里有九个精确的二进制数字,但只有三个十进制数字(511)。

考虑i.11111111111111111111111(i + 23个)* 2 ^ -1。 我们将获得具有24个二进制和24个十进制数字精度的分数(2 ^(24-1)^ /(2 ^ 24))。 给定适当的printf格式,将显示所有24位十进制数字。 乘以2 ^ 24,你仍然有24个二进制数字的精度,但只有8位小数(16777215)。

现在考虑i.1111100 ... * 2 ^ 2,它出现在7.875。 i11是整数部分,111是分数部分(111/1000或7/8)。 6位二进制数字的精度和4位小数。

做浮点时的思维十进制对于理解它是完全不利的。 释放自己!

如果您只对该值感兴趣,可以使用double,然后将结果乘以10 ^ 6并将其置于最低位置。 再次除以10 ^ 6,您将得到截断值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM