php - 为什么 PHP 和 JavaScript 在处理八进制和十六进制数时会出现问题?

标签 php javascript casting hex octal

我注意到 PHP 和 JavaScript 在类型转换和转换时处理八进制和十六进制数字有些困难:

PHP:

echo 16 == '0x10' ? 'true' : 'false'; //true, as expected
echo 8  == '010'  ? 'true' : 'false'; //false, o_O

echo (int)'0x10';    //0, o_O
echo intval('0x10'); //0, o_O
echo (int)'010';     //10, o_O
echo intval('010');  //10, o_O

JavaScript:

console.log(16 == '0x10' ? 'true' : 'false'); //true, as expected
console.log(8  == '010'  ? 'true' : 'false'); //false, o_O

console.log(parseInt('0x10')); //16, as expected
console.log(parseInt('010'));  //8, as expected
console.log(Number('0x10'));   //16, as expected
console.log(Number('010'));    //10, o_O

我知道 PHP 有 octdec()hexdec() 函数来纠正八进制/十六进制的不当行为,但我希望 intval( ) 处理八进制和十六进制数,就像 JavaScript 的 parseInt() 一样。

无论如何,这种奇怪行为背后的基本原理是什么?

最佳答案

假设有人将 035 指定为某种产品的购买数量(前导 0 仅用于填充,因此它与列表中的其他三位数数量相匹配)。对于非程序员,035 显然会像 35 一样被解释。但是如果 PHP 解释字符串中的八进制数,结果会突然变成 29 => WTF?!?另一方面,十六进制表示法问题较小,因为人们通常不使用 0x23 表示法指定数字。

顺便说一句,这不仅发生在最终用户身上,也发生在程序员身上。程序员经常试图用前导零填充他们的数字 - 哈,一切都错了!这就是为什么 JS 不再允许在严格模式下使用八进制符号,而其他语言使用更明确的 0o 前缀。

顺便说一句,我同意这种行为是不一致的。在我看来,十六进制符号也不应该被解析。就像八进制和二进制符号一样不是。特别是考虑到显式 (int) 转换也不解析十六进制,而是只读取第一个非数字之前的所有内容。


针对 intval 的情况,它实际上的行为就像记录的那样:intval 不是用于解析 PHP 的 native 整数符号,而是用于解析 指定的基地。如果你看看 docs ,您会发现它需要第二个参数 $base,默认为 10。 (顺便说一句,(int) 在内部映射到相同的 convert_to_long_base 调用,使用 base = 10,因此它的行为始终与 intval.)

关于php - 为什么 PHP 和 JavaScript 在处理八进制和十六进制数时会出现问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8261815/

相关文章:

javascript - Meteor:发布动态请求的项目范围

c++ - 调用父虚函数

javascript - PHP:如何使用unicode字符将文件写入磁盘

javascript - 是否有类似终止开关的解决方案可以将域远程重定向到子文件夹?

php - 如何理解更新语句是否成功运行?

javascript - RegExp 替换在再次替换时导致错误结果

mysql - 围绕 DECIMAL 数据类型转换的令人不安的 mysql 行为

go - 在 Go 中强制映射类型

java - Android Json HttpGet/Post HttpResponse

php - 在 WordPress 和 SQL 查询之间注入(inject)中间件的最佳方法是什么