Как вы понижаете масштабность?

perl -Mbigrat -E'for (1..100) { $i += 1/3; say int($i), "\t", sprintf "%.55f", $i }'

спамит много предупреждений:

Argument "100/3" isn't numeric in addition (+) at …/site_perl/5.24.1/Math/BigRat.pm line 1939.

Запустите снова без -Mbigrat, чтобы увидеть желаемый эффект от sprintf.

Как вы понижаете Math::BigRat экземпляр $i до обычного NV, восхитительного до sprintf?

Версии:

  • bigrat 0,47
  • Math::BigRat 0,2612

Ответ 1

Я ожидал, что Math::BigRat предоставит метод для получения простого числа, и он делает:

  • as_int для целых чисел
  • as_float для поплавков

Я вставил печать $_ для целей отладки.

$i->as_int() делает то же самое, что и int($i):

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_int() }'
...
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      33.0000000000000000000000000000000000000000000000000000000

$i->as_float(), казалось, сработал, как и ожидалось, на первый взгляд, но я не понимаю вывод. Все десятичные разряды равны нулю и для каждой второй строки $i равны $_:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", sprintf "%.55f", $i->as_float() }'
...
90      30      30.0000000000000000000000000000000000000000000000000000000
91      30      91.0000000000000000000000000000000000000000000000000000000
92      30      92.0000000000000000000000000000000000000000000000000000000
93      31      31.0000000000000000000000000000000000000000000000000000000
94      31      94.0000000000000000000000000000000000000000000000000000000
95      31      95.0000000000000000000000000000000000000000000000000000000
96      32      32.0000000000000000000000000000000000000000000000000000000
97      32      97.0000000000000000000000000000000000000000000000000000000
98      32      98.0000000000000000000000000000000000000000000000000000000
99      33      33.0000000000000000000000000000000000000000000000000000000
100     33      100.0000000000000000000000000000000000000000000000000000000

Это Perl 5.30.0 с Math :: BigRat 0.2614.

Таким образом, предупреждения исправлены, но, похоже, что-то не так с этим решением.

Обновление: В соответствии с запросом в комментариях без sprintf:

$ perl -Mbigrat -E'for (1..100) { $i += 1/3; say $_, "\t", int($i), "\t", $i->as_float() }'
...
90      30      30
91      30      91
92      30      92
93      31      31
94      31      94
95      31      95
96      32      32
97      32      97
98      32      98
99      33      33
100     33      100

Ответ 2

Не так серьезно ответ:

use bigrat;
use feature 'say';
for (1..100) {
    $i += 1/3;
    no bigrat;
    say int($i),"\t",sprintf "%.55f", eval "$i"
}