提问者:小点点

Raku中的有理数


我使用Raku进行一些计算,因为它有很好的数字类型。但是,我在使用“. raku”时遇到了问题

say (1/6+1/6).raku
#<1/3>

我们得到这个。然而,

say (1/10+1/10).raku
#0.2

是bug吗?我料到了


共3个答案

匿名用户

在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 ~ '>'
            }
        }
}