Почему мое очень маленькое число не сохраняется точно?

В ответе на StackOverflow en Español я показал, что Perl 6 избегает ошибок вычислений многих других языков, поскольку сохраняет трек числителей и знаменателей. То есть десятичные числа фактически представлены как отношения. Однако он делает небольшую ошибку с очень маленькими числами:

> 0.000000000000000000071.nude.perl
(71, 1000000000000000000000)
> 0.0000000000000000000071.nude.perl
(71, 10000000000000000000000)
> 0.00000000000000000000071.nude.perl
(71, 99999999999999991611392)

Будет ли это исправлено в будущих версиях?

Я получаю те же ответы, используя perl6/rakudo-star-2015.09 и perl6/rakudo-star-2015.11


person Christopher Bottoms    schedule 04.12.2015    source источник
comment
Это должно быть ошибкой или преобразовано в Num. Предполагается, что крыса может иметь знаменатель не более uint64.Range.max. 18446744073709551615 (20 цифр) Если вам нужен Rational с таким большим знаменателем, используйте FatRat. FatRat.new(71,10²³) или 71.FatRat / 10²³   -  person Brad Gilbert    schedule 04.12.2015
comment
@BradGilbert: +1 - Я еще не видел вашего комментария, когда писал свой ответ :(   -  person Christoph    schedule 04.12.2015


Ответы (1)


Предполагается, что знаменатели должны быть ограничены 64-битными - вам понадобится FatRat, чтобы выйти за рамки этого.

Однако указанный лимит не применяется в текущем Rakudo: если вы сделаете это вручную, он с радостью построит ваш номер через Rat.new(71, 10**23).

Я предполагаю, что вы обнаружили ошибку в обработке рациональных литералов, , но она может срабатывать только в коде, который в любом случае не рассчитан на будущее.

edit: Можно использовать угловые скобки для получения алломорфного значения, и это дает правильное значение. Фактически, обычные рациональные литералы также требуют возврата к RatStr при переполнении.

Однако этот резервный механизм, похоже, не реализован в Rakudo.

person Christoph    schedule 04.12.2015
comment
Спасибо! Размышляя с точки зрения DWIM, разве мы не хотели бы, чтобы Perl 6 просто понял, что нам нужен FatRat и использовал его, или есть еще одна основная проблема? - person Christopher Bottoms; 04.12.2015
comment
@ChristopherBottoms: литералы Perl6 в целом мономорфны и не DWIM; однако есть синтаксис угловых скобок <0.5>, который делает это, и, вероятно, может быть расширен для возврата FatRatStr вместо RatStr, когда это необходимо. - person Christoph; 05.12.2015
comment
Сладкий! <0.00000000000000000000000000000000000000000000000000000000000000000071>.nude.perl дает (71, 100000000000000000000000000000000000000000000000000000000000000000000) - person Christopher Bottoms; 05.12.2015
comment
@ChristopherBottoms: \ o / лично я ожидал, что оба вида литералов будут повторно использовать один и тот же кодовый путь и будут демонстрировать идентичное поведение; вставьте высказывание о предположениях, когда вам будет удобно - person Christoph; 05.12.2015
comment
Спецификация - это набор тестов, известный как roast. Все остальное - только догадки. - person Brad Gilbert; 05.12.2015