【问题标题】:Using printf() function in PHP to print negative integer with unsigned format specifier在 PHP 中使用 printf() 函数打印带有无符号格式说明符的负整数
【发布时间】:2017-07-02 08:44:33
【问题描述】:

我有以下代码:

<?php
  $num1 = -12;
  printf("%%u = %u<br>",$num1);
?>

输出:

%u = 4294967284

我无法理解这种输出背后的原因。

【问题讨论】:

    标签: php printf unsigned-integer


    【解决方案1】:

    %u 代表无符号。如果输入负数,则会造成溢出。因此产生了这么大的数字。

    内存中的数字只是位。如果让它解释为无符号,则第一位不再是符号,而是数字的一部分。

    你想要的是:

    $num1 = -12;
    printf("%%u = %u<br>",abs($num1));
    

    它也适用于%d

    printf("%%d = %d<br>",abs($num1));
    

    【讨论】:

    • 我知道如何带来正确的结果。只是好奇心驱使我提出这个问题。谢谢。
    • 能否详细解释一下内存溢出的概念?
    【解决方案2】:

    任何无符号类型都意味着 >= 0 个值。

    这是 php 文档所说的:

    整数的大小取决于平台,尽管通常值约为 20 亿的最大值(即 32 位有符号)。 64 位平台的最大值通常约为 9E18,除了在 PHP 7 之前的 Windows 上,它始终是 32 位。 PHP 不支持无符号整数。整数大小可以使用常量 PHP_INT_SIZE 来确定,最大值使用 PHP 5.0.5 之后的常量 PHP_INT_MAX 来确定,最小值使用 PHP 7.0.0 之后的常量 PHP_INT_MIN 来确定。

    我在 Windows x64 上运行它,所以 PHP_INT_MAX 的值将是一个 64 位长的整数 (9223372036854775807)。根据您报告的值,您可能使用的是 32 位系统。

    因此,对于您的系统,带符号的 32 位整数值的范围是 -2147483648 到 2147483647。对于无符号值,它的范围是 0 到 4294967295。

    4294967284 的值是 4294967295 - 12 + 1。

    底线:如果它是正值,您可以安全地将常规 int 转换为 unsigned int。如果它是负值,则强制转换将导致上述公式生成的值 (MAX_UINT - value + 1)。有符号和无符号类型只与正值兼容。

    您可以使用 if 子句作为正确的有符号格式说明符,以准确打印值。

    希望这能解决问题。

    【讨论】:

    • 你说 PHP 不支持 unsigned int。但是你再次说无符号值从 0 到 4294967295
    • 我没有说 PHP 不支持 unsigned int。官方文档说(粗体文本来自官方 PHP 文档)。它们不提供对 unsigned int 的本机支持,因为在版本 7 之前,php 没有类型声明。他们使用我前面提到的公式以某种方式模拟 unsigned int 。这就是我想要明确的。而且有符号和无符号类型的取值范围不同。
    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 2020-10-07
    • 2016-05-29
    • 2021-07-13
    • 2012-03-14
    • 2018-02-17
    • 2017-11-16
    • 1970-01-01
    相关资源
    最近更新 更多