C ++会精确分割失去精度吗?

时间:2015-11-19 05:27:41

标签: c++ precision division

Q1:将整数除以其除数会失去精度吗?

int a=M*N,b=N;//M and N are random non-zero integers.
float c=float(a)/b;
if (c==M)
cout<<"accurate"<<endl;

Q2:传递浮点值会失去精度吗?

float a=K;//K is a random float;
if (a==K)
cout<<"accurate"<<endl;

5 个答案:

答案 0 :(得分:3)

  

Q1:将整数除以其除数会失去精度吗?

是。我使用以下程序来提出一些数字:

#include <iostream>
#include <climits>

int main()
{
   int M = 10;
   int N = 7;
   int inaccurateCount = 0;
   for (; M < INT_MAX && inaccurateCount < 10; ++M )
   {
      int a = M*N;
      float c = float(a)/N;
      if ( c != M )
      {
         std::cout << "Not accurate for M: " << M << " and N: " << N << std::endl;
         inaccurateCount++;
      }
   }

   return 0;
}

这是输出:

Not accurate for M: 2396747 and N: 7
Not accurate for M: 2396749 and N: 7
Not accurate for M: 2396751 and N: 7
Not accurate for M: 2396753 and N: 7
Not accurate for M: 2396755 and N: 7
Not accurate for M: 2396757 and N: 7
Not accurate for M: 2396759 and N: 7
Not accurate for M: 2396761 and N: 7
Not accurate for M: 2396763 and N: 7
Not accurate for M: 2396765 and N: 7
  

Q2:传递浮点值会失去精度吗?

不,它不应该。

答案 1 :(得分:2)

  

Q1:将整数除以其除数会失去精度吗?

您实际上询问将int转换为float是否会失去预测。 是的,它通常会这样做。在今天的32位(或更宽)计算机体系结构中,int存储32位数据:1位符号加31位有效数字。 float也存储32位数据,但它们是:1位符号,8位指数和23位小数部分,参见IEEE 754 single-precision floating point format(它可能不会失去16位架构的精度,但我无法检查它。)

根据浮点数,它将存储在不同的represantations中,其中一个是规范化形式,其中小数部分由隐藏的部分前置,因此,我们得到24位有效数。这比存储在int中的要少。

例如,整数01010101 01010101 01010101 01010101(二进制,仅用于更好读取的空间)不能表示为float而不会失去精度。在标准化形式中,这将是1,010101 01010101 01010101 01010101 * 2 ^ 30。因此我们在逗号后面有30个有效数字和二进制数字,它们不能存储在23位(小数部分)而不会丢失精度。实际的舍入模式定义了如何缩短值。

注意,它不取决于该值是否实际为“高”。整数01000000 00000000 00000000 00000000采用标准化格式1,000000 00000000 00000000 00000000 * 2 ^ 30。该数字在逗号后面有零个有效位,可以存储而不会丢失精度。

  

Q2:传递浮点值会失去精度吗?

没有

答案 2 :(得分:1)

  

Q1:将整数除以其除数会失去精度吗?

如果a很大,它可能会失去精度,否则(如果a小到足以完全表示为浮点数),它就不会。转换a时,实际上可能已经发生精度损失。除此之外,划分也会失去精度,但有时可能会导致这些精度损失相互抵消。

例如,N = 8388609M=5。你有(二进制)尾数100 ... 001并乘以101并最终得到101000 ... 0000101,但最后两位将四舍五入为零,你得到一个错误(浮点)(N * M ),但是当你除以5时,你会得到1000 ... 00和100的剩余部分,这意味着它应该向上舍入一步并且你得到原始数字。

  

Q2:传递浮点值会失去精度吗?

不,它不会失去精确度。但是,您的代码仍然无法将其识别为准确。

如果KNaN(例如0.0/0.0),那么可能会发生这种情况,那么x也会成为NaN - 但{ {1}}不应该(需要)比较等于。在这种情况下,人们可能会争辩说你失去了精确度并且我同意,但是在NaN处没有精确度 - 你在生成x=K时已经失去了精确度。

答案 3 :(得分:0)

它不是确切的,但为了获得更准确的答案,您可以使用值类型double和long

答案 4 :(得分:0)

案例1:是的,在某些情况下它会失去精确度。对于较小的M值,它将是准确的。

案例2:不,它不会失去精确度。