博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在 PHP 中实现整数溢出
阅读量:7156 次
发布时间:2019-06-29

本文共 1344 字,大约阅读时间需要 4 分钟。

hot3.png

在用 PHP 翻译别人用 Java 写的如下一段代码时,碰到了一些关于 PHP 整数操作的问题。

Java 代码:

public static long hash(String string) {        long h = 1125899906842597L;        int len = string.length();        for (int i = 0; i < len; i++) {            h = 31*h + string.charAt(i);        }        return h;    }

由于 Long 类型的 h 的初始值就比较大,经过多次乘以 31 之后会溢出。但是移除后 h 的值也不会为 0,运算可以正常继续。但是在 PHP(5.3.27_1) 中,当整数溢出后,用 intval 取值会得到 0。而 PHP 中用来做大数运算的 BC_MATH 中的函数虽然可以进行大数运算,但是无法在溢出后截断溢出。这让人很郁闷。又不想光为这个简单的功能去用 C 写一个扩展。最后又复习了一边《深入理解计算机系统》中第二章关于整数运算的描述,写了一个整数溢出的函数。

function overflow_long($value)    {        $max_int = bcsub(bcpow(2, 63), 1);        $int_span = bcpow(2, 64);        $min_int = bcsub(bcadd($max_int, 1), $int_span);        $mod_value = bcmod($value, $int_span);        if (bccomp($mod_value, $max_int) > 0) {            return bcsub($mod_value, $int_span);        } elseif (bccomp($mod_value, $min_int) < 0) {            return bcadd($mod_value, $int_span);        } else {            return $mod_value;        }    }

然后实现上述 Java 代码的功能。

private function hash($str) {        $char_arr = str_split($str);        $len = strlen($str);        $h = 1125899906842597;        for($i=0; $i<$len; $i++) {            echo $h, "
"; $h = $this->overflow_long(bcmul(31, $h)) + ord($char_arr[$i]); } return $h; }

转载于:https://my.oschina.net/u/1412485/blog/182556

你可能感兴趣的文章
Linux系统查看系统是32位还是64位方法总结
查看>>
[Linux] Ubuntu下的文件比较工具--meld
查看>>
普通Java类获取spring 容器的bean的5种方法
查看>>
Android使用百度定位SDK 方法及错误处理
查看>>
延迟加载与序列化
查看>>
SQL基础--&gt; 约束(CONSTRAINT)
查看>>
Integer 与int 的区别
查看>>
Linux 小知识翻译 - 「DNS服务器」
查看>>
【开发实例】C#调用SAPI实现语音合成的两种方法
查看>>
struts1配置文件之input
查看>>
javascript跨域解决方案
查看>>
#HTTP协议学习# (一)request 和response 解析
查看>>
Cloud Foundry中gorouter对StickySession的支持
查看>>
尚福林:三家民营银行获准筹建
查看>>
我的Android开发相关文章
查看>>
汇编中Enter与Leave指令
查看>>
int *
查看>>
String,StringBuffer与StringBuilder的差别??
查看>>
巴菲特名言
查看>>
普林斯顿公开课 算法2-3:插入排序
查看>>