我有时这样用:
$ perl -e "printf "%d", ((~18446744073709551592)+1)"
24
我似乎不能和Raku一起做。我能得到的最好的是:
$ raku -e "say +^18446744073709551592"
-18446744073709551593
那么:我怎样才能让Raku给我和Perl一样的答案呢?
必须使用(我的变体)Liz的自定义op(在她的评论中)。
sub prefix:<²^>(uint $a) { (+^ $a) + 1 }
say ²^ 18446744073709551592; # 24
我最初的"半信半解的胡乱猜测",后来被@zentrunix接受了,这也是Liz的op的基础:
say (+^ my uint $ = 18446744073709551592) + 1; # 24
o/成功了!³
<标题>脚注h1> 翻转了两个字符op,因为我想遵循+^
的形式,让它的发音为"two’s complementary",并避免它看起来像^2
。
²一条思路是关于特定的整数。我看到18446744073709551592
接近2**64
。另一个是整数在Perl中是有限精度的,除非你做了什么使它们不同,而在Raku中它们是任意精度的,除非你做了什么使它们不同。第三种思路来自于阅读前缀+^
的文档,它说"使用尽可能多的字节将数字转换为二进制"。我把它理解为某种程度上表现是很重要的。嗯。如果我尝试int
变量呢?溢出。(当然)。uint
吗?宾果。
uint
被定义为对应于用于编译Raku代码的Raku编译器所支持的最大原生无符号整数大小。(这个)。在今天的实践中,这意味着Rakudo和任何底层平台都是目标,我认为几乎可以肯定的是,在几乎所有情况下,这意味着C的uint64_t
。我想perl
有一些类似的平台相关定义。所以我的解决方案,如果它是一个合理的,大概只能移植到Raku编译器(在实践中今天意味着Rakudo)与perl
二进制文件(在实践中今天意味着P5P的perl
)在某些平台上运行时的程度。请参阅下面@p6steve的评论。
标题>"火车"答:
raku -e 'put ( (18446744073709551592.base(2) - 0b1).comb.map({!$_.Int+0}).join.parse-base(2));'
或
raku -e 'say 18446744073709551592.base(2).comb.map({!$_.Int+0}).join.parse-base(2) + 1;'
示例输出:24
以上答案(应该?)实现"两个互补";直接编码。两者都不使用Raku的+^
双补运算符。第一个从二进制表示中减去1,然后反转。第二个先反转,然后加1。两个答案感觉都不正确,但得到了与Perl5相同的答案(24
)。
看看Raku文档页面,人们会得出这样的结论:"两个互补";一个正数的负数,因此目前还不清楚什么代表Perl(现在乐烧)的答案。希望以上内容对您有所帮助。
https://docs.raku.org/routine/+ $ CIRCUMFLEX_ACCENT