【问题标题】:Why double is not storing the product of two int [duplicate]为什么 double 不存储两个 int 的乘积 [重复]
【发布时间】:2018-02-21 17:38:48
【问题描述】:

我正在尝试了解数字如何存储在计算机内存中的基本知识。因此,我最近开始学习 C++。我编写了以下函数,用于计算任何 int 值的平方。

 // since integer can go upto 65K value, hence the return
 // value is double to accomodate the square of highest int value.
 double square(int val) {
     return val*val;
 }

为什么65535 给我一个错误的答案,据我了解,这是int 类型变量中可以存储的最大数字?我还发现有这样的东西:

std::numeric_limits<int>::max()

这给了我2147483647。这反过来让我更加困惑,但我正在寻求解释为什么我的 square 函数失败了。

编辑

对于65535,我的g++ 编译器给了我:-131071

【问题讨论】:

  • 存储在 int 中的最大值实际上取决于您的编译器和 int 的字节数,如果您有一个 unsigned int,即 2 个字节(16 位),那么 65535 将是最大的价值。在这种情况下,一个 int 似乎是有符号的,并且是 4 个字节。
  • 16 位 int 不能容纳 65535 作为最大值。最大的将是 32767,因为 int 已签名。如果您的字是 16 位,您可能希望 unsigned int 的最大值为 65535。还是您的int 32 位?从你的问题不清楚。另外,当您说错误答案时,您看到哪些答案是您认为错误的?这篇文章总体上很不清楚。
  • 您对int 的最大大小做出了错误的假设。它可能因平台/编译器而异。 C++ 标准为您提供的所有内容都是有保证的最小 大小。
  • 有关最小整数大小的信息,请参阅 cppreference.com - Integer types
  • 除非你转换为double乘法之前,你仍然在执行有符号整数乘法,在溢出的情况下其行为是不确定的。您只是将最终结果投射到 double,这没有帮助。

标签: c++


【解决方案1】:

您在这里有符号整数溢出,这是未定义的行为。你说std::numeric_limits<int>::max() 给了2147483647,因为65535 比你觉得你应该没问题。问题是你不是。当您将int 相乘时,结果将存储在int 中(即使这不是您分配给它的内容)。由于65535 * 655354294836225,它会溢出结果。

解决此问题的唯一方法是使用可以容纳结果的更宽/更大的类型。例如,如果你将两个long long 相乘,你可以做65535 * 65535 并且没问题。

只要乘法中至少一个变量的类型足够大以存储结果,那么你就可以了。所以在这种情况下,两个

val * static_cast<double>(val)

val * static_cast<long long>(val)

会给你正确的结果。您也可以将 val 更改为 double,这样也可以解决问题。

【讨论】:

  • 另外,由于所需的最终结果是double,我相信val * (double) val 就足够了,以浮点类型的不精确为模。
  • “唯一的方法”?
  • @bolov 如何在不使用更大数据类型的情况下存储更大的值?
  • 我使用double 来包含65535*65535 的输出。我对 C++ 的了解非常有限。
  • @RajatSaxena 在这种情况下,我相信我对这个问题的评论可能就是您想要的。你只是投到double 太晚了。
猜你喜欢
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 2019-09-10
  • 2015-04-21
  • 1970-01-01
  • 2018-09-17
  • 2019-09-22
  • 2016-06-28
相关资源
最近更新 更多