Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java等效的无符号long long不是BigInteger?_Java_C_Long Integer_Biginteger - Fatal编程技术网

Java等效的无符号long long不是BigInteger?

Java等效的无符号long long不是BigInteger?,java,c,long-integer,biginteger,Java,C,Long Integer,Biginteger,我有一个简单的C代码,它使用无符号long-long: #include<stdlib.h> unsigned long long get_random_id(const char *imeiId) { const unsigned long long MULT = 2862933555777941757LL; const unsigned long long ADDEND = 3037000493LL; unsigned long long newId, o

我有一个简单的C代码,它使用无符号long-long:

#include<stdlib.h>
unsigned long long get_random_id(const char *imeiId)
{
    const unsigned long long MULT = 2862933555777941757LL;
    const unsigned long long ADDEND = 3037000493LL;
    unsigned long long newId, oldId;
    oldId = atoll(imeiId);
    newId = MULT * oldId + ADDEND;
    return newId;
}
void main()
{
  printf("%llu",get_random_id("351746051295833"));
}
我这里的问题是,Java和C代码的输出不一样。 对于C代码,我得到10076018645131828514。而对于Java代码,我得到的是100702557336722946839210487799074

对于相同的输入,我无法理解这些不同的输出


PS:我在Ubuntu 32位机器上运行代码,使用gcc编译器

unsigned long
是一种有限长度的整数格式(可能)。这意味着它不能保存大于264-1的值

biginger
是任意长度的整数格式。这意味着存储在
biginger
中的数字的大小实际上仅受可用内存的限制(以及一些JVM限制,如数组的大小,但这些限制非常大)

在C程序的计算中,
无符号long-long
可能会溢出,您会得到一个截止结果

对于
BigInteger
(它不会自动溢出),它只会给出准确的结果

您可以通过创建包含所需位掩码(64个设置位)的
biginger
并使用
myValue.and(mask)
获得“溢出”结果来模拟溢出


不过,你必须在可能发生溢出的每一步都这样做。而且它肯定比C代码慢。

long
s依赖于平台。你不能指望它们是便携式的,或者在其他机器上是相同大小的


尝试执行
sizeof(unsigned long-long)
以查看它在您的计算机上的实际大小。尽管我猜测您正在溢出。

如果您执行实际乘法,Java的输出是正确的

我使用Python查找以下内容:

>>> 2862933555777941757 * 351746051295833 + 3037000493
1007025573367229468539210487799074L
然后,要获取C代码中的内容,请执行以下操作:

>>> 2862933555777941757 * 351746051295833 + 3037000493
1007025573367229468539210487799074L
>>> _ % (2**64)   # Previous result mod 2 ^ 64 (**Assumming ULL is 64 bits on your system**)
10076018645131828514L  # This is what you have as the output of your C code.

您有一个未签名的长环绕。:)

要正确计算答案,您需要一个至少能处理110位的类型。我怀疑在您的平台上,C
无符号long
可能只有64位,这是不够的。满溢了


Java程序的答案是正确的。

这是一个广泛使用的线性同余生成器:

(286293355577941757*N+3037000493)%2^64


模数部分由字大小以零成本提供,在本例中为64位,因此未包含在C代码中。使用多精度算法的任何版本的代码都是错误的,它必须是64位。状态的一个好数据类型是uint64\u t。

C程序的答案太短了。在您的平台上,无符号long-long有多少位?不管它有多少,都不足以容纳答案。乘法
MULT*oldId
溢出。是~10^33。
unsignedlong-long
decimal是什么意思?它在
2**64-1
处溢出不是意味着它是二进制的吗?@svk:这是一个打字错误(或think-o):我实际上是指整数,我把它和
bigdecime
混在一起了,它是
bigteiger
的“表亲”,但与这个问题无关。是的,现在我明白了。在我的机器上,unsigned long long是64位
>>> 2862933555777941757 * 351746051295833 + 3037000493
1007025573367229468539210487799074L
>>> _ % (2**64)   # Previous result mod 2 ^ 64 (**Assumming ULL is 64 bits on your system**)
10076018645131828514L  # This is what you have as the output of your C code.