【问题标题】:How to detect integer hex value like 0x0a如何检测整数十六进制值,如 0x0a
【发布时间】:2016-01-25 16:06:12
【问题描述】:

我有一个工作函数(我认为)可以正确检测像(int) 0, -1, +1(string) '0', '-1', '+1' 这样的有效整数,但是该函数失败并且十六进制值也被检测为整数。这意味着如果我将整数值 0x0a 传递给函数,它会返回 true。这只影响if (is_int($input) === true) { 部分。我怎样才能避免这种情况发生?

工作示例:

function isInteger($input)
{
    if (is_scalar($input) === false) {
        return false;
    }

    if (intval($input) == $input) {
        if (is_string($input) === true && ctype_digit(ltrim($input, '+-')) === true) {
            return true;
        } else
        if (is_int($input) === true) {
            return true;
        }
    }

    return false;
}

【问题讨论】:

  • 不起作用,php 以某种方式将存储在变量中的值转换为整数,例如:testHexValue = 0x0a;变为 testHexValue = 10;。可悲的是。正则表达式只有在 0x0a 值是像 testHexValue = '0x0a'; 这样的字符串时才有效
  • 您在这里混淆了您的条款。 0x0a 是一个整数 - 它相当于十进制 10。您不是在尝试检测整数,而是在尝试检测整数的 十进制 表示,这是另一回事。你可能不得不求助于正则表达式来做你想做的事。 php.net/manual/en/language.types.integer.php
  • 谢谢@DanLowe。是的,你是对的,我正在尝试检测整数的十进制表示。以这种方式编写decvalue = 0x0a; 是否可能,因为当我执行var_dump()var_export() 时,我得到的只是十进制10,正如你所写的那样。
  • 据我所知,无法检测到这一点。十六进制、八进制、二进制表示只是格式化。整数始终是内存中的数值。许多语言是相同的,例如在这种情况下,Python 会做同样的事情,就像在 x = 0x0a; print(x); 中一样 - 将返回 10 作为结果。
  • 我有一种感觉,在这种情况下,我必须分别对字符串和整数中的数字进行验证。我是如此接近解决一个总是困扰我的问题,但是随着验证布尔值的出现,然后......我必须重新考虑我的验证策略。谢谢@DanLowe,非常感谢您的回答。

标签: php string integer


【解决方案1】:

我认为您在这里混淆了一些术语。 0x0a 是一个整数 - 它相当于十进制 10。您不是在尝试检测整数,而是在尝试检测整数的十进制表示,这是另一回事。

在 PHP 中,与在许多其他语言中一样,整数就是整数。在底层,所有这些值都是等价的并以相同的方式存储在内存中

10         # decimal
012        # octal
0x0a       # hexadecimal
00001010   # binary

这些语言中的大多数都是用 C 或 C++ 实现的,并使用 C int 系列之一来存储这些值。

即使您可以将它们指定为其他格式,例如八进制或十六进制,并且您可以将它们格式化为输出,它们在内存中仍然是整数值。

我怀疑你最好的选择是使用正则表达式。但是,这取决于是否有可用的字符串表示。因为猜猜当你将整数转换为字符串时会发生什么......是的,你得到了十进制表示。

echo strval(0x0a);
# outputs "10"

在 PHP 中显示此问题的示例:

$x = 10;
$y = 012;
$z = 0x0a;

echo "x:$x y:$y z:$z\n";

foreach (array(10, 012, 0x0a) as $i) {
    echo var_dump($i);
    echo var_export($i) . "\n";
}

输出:

x:10 y:10 z:10
整数(10)
10
整数(10)
10
整数(10)
10

PHP 在这种情况下并不是唯一的。其他语言的行为方式完全相同。

Python

w = 10
x = 0o12
y = 0x0a
z = 0b1010

print('w:{} x:{} y:{} z:{}'.format(w, x, y, z))

for i in (10, 0o12, 0x0a, 0b1010):
    print(repr(i), i)

输出:

w:10 x:10 y:10 z:10
10 10
10 10
10 10
10 10

Perl

use strict;
use Data::Dumper;

my $x = 10;
my $y = 012;
my $z = 0x0a;

print "x:$x y:$y z:$z\n";

for my $i (10, 012, 0x0a) {
    print Dumper($i);
}

输出:

x:10 y:10 z:10
$VAR1 = 10;
$VAR1 = 10;
$VAR1 = 10;

C

#include <stdio.h>

int main(void) {

    int x = 10;
    int y = 012;
    int z = 0x0a;

    printf("%d %d %d\n", x, y, z);
    printf("0%o 0%o 0%o\n", x, y, z);
    printf("0x%x 0x%x 0x%x\n", x, y, z);

    return(0);

}

输出:

10 10 10
012 012 012
0xa 0xa 0xa

【讨论】:

  • 感谢@Dan Lowe,这就是我要找的东西!
【解决方案2】:

正如@Dan Lowe 所写:

据我所知,无法检测到这一点。十六进制、八进制、二进制表示只是格式化。整数始终是内存中的数值。许多语言是相同的,例如在这种情况下,Python 会做同样的事情,就像 x = 0x0a;打印(x); - 将返回 10 作为结果。

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2015-07-26
    • 2021-09-29
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2023-02-15
    • 2014-01-04
    相关资源
    最近更新 更多