0

我想乘以 2^32 为基础的长数。我已经想到了一个很好的算法来做到这一点,但不幸的是我被卡住了。我遇到的情况是我如何将两个长整数相乘并在 2^32 的基础上表示它。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef unsigned int uint32;
typedef unsigned long long uint64;
int main(int argc, char* argv[] )
{

  uint64 a = (uint64)ULONG_MAX;
  printf("%llu\n", a);
  uint64 b = (uint64)ULONG_MAX;  
  printf("%llu\n", b);  
  uint64 c = (uint64)(a*b);

  printf("%llu\n", c);  // prints 1. that would be to lower 32 bits of the results. the upper half is 0xFFFFFFFE

  printf("%llu\n", ULLONG_MAX);
  system("pause");
}

为什么 ULLONG_MAX 与 ULONG_MAX 相同?根据http://en.wikipedia.org/wiki/Limits.h#Member_constants它应该是 18,446,744,073,709,551,615 我

从我的评论中可以看出,我想要两个 uint32 中的乘法结果。下半部分为 0x1,上半部分为 0xFFFFFFFE。我如何获得这些值?

(我在 SO 上找到了这个问题,但这对我的情况没有帮助,因为给出的答案与我的想法相似:乘以两个 long long ints C

编辑: 我的系统是 Windows XP 32 位。我正在使用 gcc 3.4.2 (mingw-special)

我在运行代码时得到的输出:

4294967295
4294967295
1
4294967295

编辑2:

  printf("%i\n", sizeof(unsigned long));
  printf("%i\n", sizeof(unsigned long long)); 

返回

4
8

编辑3: 感谢Petesh,我能够找到解决方案:

  printf("%lu\n", c & 0xFFFFFFFF);
  printf("%lu\n", (c >> 32));
4

2 回答 2

5

提示在系统中(“暂停”) - 你在 Windows 上?使用 Microsoft Visual c 运行时打印 long long 需要使用 '%I64u'(这是一个大写字母 i)。

这是基于 SO 问题How do you printf an unsigned long long int(unsigned long long int 的格式说明符)?

于 2010-08-22T16:16:49.280 回答
3

不知道为什么你用你的(未指定的)编译器得到这些结果,但gcc在 Ubuntu 10 下给出:

4294967295
4294967295
18446744065119617025
18446744073709551615

最后两个分别是0xfffffffe00000001和 (2 64 -1),如您所愿。

所以也许考虑切换到更新的编译器。您可能正在使用 C99 之前的编译器。

只是出于兴趣,您的系统上有什么功能sizeof (unsigned long)和功能。sizeof (unsigned long long)这将大大有助于解释您的问题。


sizeof由于您的 s 似乎表明数据类型本身是可以的(尽管这些可能无法解决问题 - 它们是通过相当浅的网络搜索找到的),因此需要检查其他几件事:

  • 尝试使用"%I64u"作为格式字符串而不是"%llu". 如果 MinGW 使用 MSVCRT 库,则可能需要真正的 64 位printf支持。
  • 确保您使用-std=c99.
于 2010-08-22T16:06:26.943 回答