首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >php 64位整数溢出与Java内嵌不同

php 64位整数溢出与Java内嵌不同
EN

Stack Overflow用户
提问于 2014-07-27 14:43:37
回答 3查看 115关注 0票数 0

我试图在php中实现java的随机类,几个小时后,我发现php在将两个64位长相乘时返回的值与java的值不同。

In php

代码语言:javascript
复制
echo (int) (160577175182 * 25214903917);

给出

代码语言:javascript
复制
9101091335015235584

在Java小程序中

代码语言:javascript
复制
g.drawString( "Java: " + (160577175182L * 25214903917L), 10, 10 );

给出

代码语言:javascript
复制
Java: 9101091335015183990

有趣的是,如果您将它放入程序员模式的calc中,它也会产生9101091335015183990。

25214903917是java随机幻数0x5DEECE66D

160577175182是一个测试种子值。

我知道结果数大于64位数,因此两者的结果都是不正确的。我只需要能够在php中复制java结果。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-28 13:02:47

与mrVoid的伟大洞察力

代码语言:javascript
复制
private function java_multi($large_a,$large_b)
{
    $mul_str = bcmul($large_a,$large_b);
    $hex = $this->dec2hex($mul_str);
    $hex = substr($hex,-16);
    return (int) $this->hex2dec($hex);
}

感谢乔斯特

代码语言:javascript
复制
function dec2hex($number)
{
    $hexvalues = array('0','1','2','3','4','5','6','7',
               '8','9','A','B','C','D','E','F');
    $hexval = '';
     while($number != '0')
     {
        $hexval = $hexvalues[bcmod($number,'16')].$hexval;
        $number = bcdiv($number,'16',0);
    }
    return $hexval;
}

// Input: A hexadecimal number as a String.
// Output: The equivalent decimal number as a String.
function hex2dec($number)
{
    $decvalues = array('0' => '0', '1' => '1', '2' => '2',
               '3' => '3', '4' => '4', '5' => '5',
               '6' => '6', '7' => '7', '8' => '8',
               '9' => '9', 'A' => '10', 'B' => '11',
               'C' => '12', 'D' => '13', 'E' => '14',
               'F' => '15');
    $decval = '0';
    $number = strrev($number);
    for($i = 0; $i < strlen($number); $i++)
    {
        $decval = bcadd(bcmul(bcpow('16',$i,0),$decvalues[$number{$i}]), $decval);
    }
    return $decval;
}

java_multi(160577175182,25214903917)

返回

9101091335015183990

和java一样。

票数 0
EN

Stack Overflow用户

发布于 2014-07-27 16:41:05

我使用Java中的扩展算术类进行了一些测试,得出了以下结论:

PHP结果与对整数形式的未舍入输入进行乘法一致,但随后将结果转换为64位浮点。

以下结果中的所有数字都是十六进制的,因为它更容易看到正在发生的事情。

完整的产品是db7e4d92597bf73676

舍入IEEE 754 64位浮点数的产品是db7e4d92597bf80000。

Java结果是7e4d92597bf73676,是整个产品中最不重要的64位。

PHP产品为7e4d92597bf80000,是产品双转换整数值中最不重要的64位。

我不是PHP专家。PHP有扩展的整数数据类型或库吗?为了得到正确的结果,必须从产品中提取低阶64位,而不必首先转换为浮点。

票数 3
EN

Stack Overflow用户

发布于 2014-07-27 15:06:32

正确的结果是:4048938043477406987894

这是一个72位数。所以有一个溢出。

4048938043477406987894 mod (2^64) = 9101091335015183990部件是正确的

php实现可能是由PHP_INT_MAX舍入的,应该给出9101091335015184428

因此,我的猜测是检查PHP_INT_MAX并将其用作for实现。

它可能也是echo (int) (160577175182 * 25214903917);echo (int) (int)160577175182 * (int)25214903917;不同的地方

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24982058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档