在C中:
printf ("%u", 17860374324089702869);
打印“ 3336554965”(这是我想要的答案!)
在perl中,同一行代码显示为“ 17860374324089702869”。
如何从“ 17860374324089702702”中获得perl来生产“ 3336554965”。
我的直觉说这是64位与32位的问题,但是似乎perl语句对数字没有任何作用。
答案 0 :(得分:5)
在C中,printf
%u
取unsigned int
。这是32位还是64位值还是完全不同的值取决于您的C实现。该标准仅要求int
至少为16位宽。 (由于您在示例中传递的值不适合unsigned int
,因此我很确定您的代码具有未定义的行为:您没有将unsigned int
传递给{{1} },就像您期望的那样。)
在Perl中,%u
将其参数转换为无符号整数。该整数的宽度取决于Perl的编译方式。它通常是32位或64位类型。您可以通过运行%u
(Perl的无符号整数类型的大小,以字节为单位)和perl -V:uvsize
(对应的C类型)来查询perl的配置详细信息。
如果您想将值显式地截断为32位,则最简单的方法可能是应用位掩码:
perl -V:uvtype
那您也不需要use constant { UINT32_MAX => 0xffff_ffff };
print 17860374324089702869 & UINT32_MAX, "\n";
。
答案 1 :(得分:1)
在Perl中没有这样的无符号32位整数。 17860374324089702869在C中变为3336554965,因为无符号32位整数的范围为0到4294967295,当发生溢出时,该整数将从下界出现,反之亦然
例如
unsigned int a = 4294967296 // will be 0 because unsigned integer upper limit is 4294967295
因此您只需要将其与4294967296进行模块化,因为从0到4294967295之间有4294967296个数字
#!/usr/bin/perl
printf "%09u", 17860374324089702869 % 4294967296
答案 2 :(得分:0)
这通常与Perl的printf
/ printf
无关,而与Perl如何存储整数并将整数传递给函数有关。如其他答复所述,Perl中没有32位整数类型。
基本上,您需要剥离64位整数的一半以使其成为32位。为此,只需使用二进制sprintf
:
&
在这里,perl -e 'printf("%09u\n", 17860374324089702869 & 0xffffffff);'
3336554965
操作保留低4个字节的位不变,但是将高4个字节的位设置为零。
答案 3 :(得分:0)
C语言具有大量的数字数据类型(和大小)。 Perl具有3种数据类型-“ scalars, arrays of scalars, and associative arrays of scalars”,
在Perl中,标量值是多态的,因此根据使用方式,可以将值 17860374324089702702 视为字符串或数字。在printf语句中使用时,将其视为编号17860374324089702869,并按此格式打印。
在C中,将无符号整数视为在要为其编译程序的体系结构上由字长指定的范围内的整数。编译时应该已经收到警告。当我用-Wall编译以上语句时,这是我得到的警告:
警告:格式为'%u'的参数类型为'unsigned int',但是参数2的类型为'__int128'[-Wformat =]
See this post discussing the maximum integer value that can be count to in Perl.