我使用Raku进行一些计算,因为它有很好的数字类型。但是,我在使用“. raku”时遇到了问题
say (1/6+1/6).raku
#<1/3>
我们得到这个。然而,
say (1/10+1/10).raku
#0.2
是bug吗?我料到了
在Raku中,0.2
构造一个Rat
,因此产生与编写1/5
(将常量折叠)或相同的结果
. raku
(以前称为.perl
)方法的工作是产生一些东西,如果EVAL
'd,它会往返并产生相同的值。在1/5
的情况下,它可以精确地表示为十进制,因此它会产生0.2
。它只在十进制形式不会往返时使用分数表示。
您始终可以使用。分子
和。分母
方法来恢复分子和分母,以根据需要进行格式化。此外,. nur
方法返回分子和分母的列表,如果需要,可以将其与/
连接:
say (1/6+1/6).nude.join("/"); # 1/3
say (1/10+1/10).nude.join("/"); # 1/5
嗨@milou123我也有点惊讶raku恢复到十进制表示——我可以看到一些上下文——比如教授分数算术将受益于“保持为老鼠”模式。话虽如此,最终只有一种方法可以. raku某事,十进制是默认表示。
当然,使用raku,您也可以稍微更改一下语言。在这种情况下,我发明了一个新的“→”后缀运算符……
multi postfix:<→> ( Rat:D $r ) { $r.nude.join("/") }
say (1/5+1/5)→; # 2/5
我不够聪明,无法弄清楚内置的'raku'方法是否可以以类似的方式被覆盖,我很想知道如何简洁地做到这一点…
在Julia中试试这个:
julia> 1 // 10 + 1 // 10
1//5
julia> typeof(1 // 10 + 1 // 10)
Rational{Int64}
julia> 1 // 2 + 1 // 3
5//6
julia> typeof(1 // 2 + 1 // 3)
Rational{Int64}
在Rat. pm6实现中,我们只能在Rat类型上调用.raku
方法来获取预期的格式:
multi method raku(Rat:D: --> Str:D) {
if $!denominator == 1 {
$!numerator ~ '.0'
}
else {
my $d = $!denominator;
unless $d == 0 {
$d = $d div 5 while $d %% 5;
$d = $d div 2 while $d %% 2;
}
if $d == 1 and (my $b := self.base(10,*)).Numeric === self {
$b;
}
else {
'<' ~ $!numerator ~ '/' ~ $!denominator ~ '>'
}
}
}