2 补码算术的 Raku 运算符?

  • 本文关键字:Raku 运算符 补码 raku
  • 更新时间 :
  • 英文 :


我有时这样用:

$ 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吗?宾果。

我不知道这个解决方案是否出于错误的原因是正确的。甚至更糟。值得关注的是,Raku中的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

最新更新