5

我有以下代码:

#include <iostream>
#include <limits>

int main()
{
   std::cout << std::numeric_limits<unsigned long long>::digits10 << std::endl;
   return 0;
}
  • GCC 4.4 返回 19
  • MS VS 9.0 返回 18

有人可以解释为什么两者之间有区别吗?无论编译器如何,我都希望这样的常量是相同的。

4

3 回答 3

10

如果 Visual C++ 2008 返回18for std::numeric_limits<unsigned long long>::digits10,这是一个错误(我没有安装 Visual C++ 2008 来验证所描述的行为)。

在 Visual C++ 中(至少对于 32 位和 64 位 Windows),unsigned long long它是 64 位无符号整数类型,能够表示 0 到 18,446,744,073,709,551,615 (2 64 - 1) 之间的所有整数。

因此,这里的正确值digits10是 19,因为 anunsigned long long可以表示 9,999,999,999,999,999,999(19 位)但不能表示 99,999,999,999,999,999,999(20 位)。也就是说,它可以表示每个 19 位数字,但不能表示每个 20 位数字。

使用 Visual C++ 2010 编译时,您的程序会打印预期的 19。

于 2011-05-08T06:48:03.370 回答
0

numeric_limits::digits10指定可以在不损失精度的情况下表示的小数点左侧的小数位数。所以,我猜它会因编译器而异,具体取决于它们的实现细节。

于 2011-05-08T06:26:43.867 回答
0

一般来说,声明

无论编译器如何,我都希望这样的常量是相同的。

不正确,因为 C 中类型的大小不固定该标准仅规定了最低限度,编译器可以自由使用更广泛的类型。例如,32 位或 64 位计算机上的一些奇怪的编译器可能具有CHAR_BIT = 9并且unsigned long long不再是 64 位,或者它可能使用不同的 1 的补码或其他一些数字编码。简而言之,编译器之间的结果可能会有所不同。

但是,如果这unsigned long long是 64 位类型,那么它肯定是一个错误。我刚刚检查并看到该错误已在 VS 2008 中修复。返回正确的值 19

于 2014-01-16T06:55:46.337 回答