11

次のことを考慮してください。

print 3 ** 333; #Yields 7.6098802313206e+158

私の質問は単純です:非常に大きな数を扱うときに科学的記数法を無効にするにはどうすればよいですか?stdout基本的に、すべての数字が逐語的にダンプされるのを見たいです。

これは可能ですか?

4

5 に答える 5

15

見るMath::BigInt

use Math::BigInt;
$x = Math::BigInt->new("3");
print $x ** 333;

出力:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523
于 2009-09-14T23:11:21.737 に答える
7

プログラム内のすべての整数に対してこれを実行する場合は、次を追加するだけです。

use bigint;

一部の整数に対してのみ実行する場合は、Math::BigIntオブジェクトを作成できます。

floatを使用している場合は、 bignumMath::BigNumもあります。

于 2009-09-15T16:01:14.777 に答える
3

非常に小さい値については、次のコードを参照してください。

my $value = 1e-07;                 # = 0.0000001

# NOPE

print $value;                      # prints 1e-07, $value is a number
print sprintf("%f", $value);       # prints 0, $value is a number
print sprintf("%.10f", $value);    # prints 0.0000001000, $value is a number
$value = sprintf("%.10f", $value);
print $value                       # prints 1e-07, $value is a number

# /NOPE

use bignum;
$value = ($value+0)->bstr();
print $value;                      # prints 0.0000001, $value is a string
no bignum;
print $value;                      # prints 0.0000001, $value is a string

# HOORAY
于 2010-03-03T14:16:14.343 に答える
2

数値が大きい場合、数値の格納に使用される精度よりも桁数が多くなる可能性があります。(簡単な実行可能な例を見ると、この質問は解決されます)。

150以上の数字をすべて表示する必要がある場合は、bigint(整数の場合)、bigrat(有理数の場合)、およびbignum(浮動小数点数の場合)モジュールを使用する必要があります。

于 2009-09-14T23:18:13.237 に答える
0

このコードで同じ問題がありました:

#!/usr/bin/perl
use strict;
use warnings;
print "Base Exp    MAX Signed-Negitive     MAX Signed-Positive            MAX Unsigned\n";
for( my $x = 1; $x <= 64; $x++ ) {
    my $y = (2 ** $x);
    printf( "2 ^ %4d = %20d to %-20d or %20d\n",
                 $x,   $y/-2,  $y/2,    $y );
}

印刷する最後の2行:

2 ^   63 = -4611686018427387904 to 4611686018427387904  or -9223372036854775808
2 ^   64 = -9223372036854775808 to -9223372036854775808 or                   -1

明らかに正しくなく、%d変換が問題の原因であることに気づかなかったので、ここでフラグが立てられた解決策を試しました。

#!/usr/bin/perl
use strict;
use warnings;
use Math::BigInt;
print "Base Exp    MAX Signed-Negitive     MAX Signed-Positive            MAX Unsigned\n";
for( my $x = Math::BigInt->new('1'); $x <= 64; $x++ ) {
    my $y = Math::BigInt->new(2 ** $x);
    printf( "2 ^ %4d = %20d to %-20d or %20d\n",
                 $x,   $y/-2,  $y/2,    $y );
}

そのとき、printf'd'変換が問題を引き起こしていることに気づきました。Math :: BigIntを読むと、これらの数値は文字列として内部に格納されていることが示唆されているようです。そのため、「s」変換に変更すると、問題が修正されました。

#!/usr/bin/perl
use strict;
use warnings;
use Math::BigInt;
print "Base Exp    MAX Signed-Negitive     MAX Signed-Positive            MAX Unsigned\n";
for( my $x = Math::BigInt->new('1'); $x <= 64; $x++ ) {
    my $y = Math::BigInt->new(2 ** $x);
    printf( "2 ^ %4s = %20s to %-20s or %20s\n",
                 $x,   $y/-2,  $y/2,    $y );
}

これで、最後の2行が正しく印刷されました。

2 ^   63 = -4611686018427387904 to 4611686018427387904  or  9223372036854775808
2 ^   64 = -9223372036854775808 to 9223372036854775808  or 18446744073709551616

しかし、ほぼ正しいIMHOであるKarelの答えに関しては、BigInt(bigint、BigNum、...)を使用せずに、「f」変換を使用してこれを行うこともできますが、精度を「0」に設定して削除します。それらの小数:

#!/usr/bin/perl
use strict;
use warnings;
print "Base Exp    MAX Signed-Negitive     MAX Signed-Positive            MAX Unsigned\n";
for( my $x = 1; $x <= 64; $x++ ) {
    my $y = (2 ** $x);
    printf( "2 ^ %4d = %20.0f to %-20.0f or %20.0f\n",
                 $x,   $y/-2,  $y/2,    $y );
}

これは、OPの質問にも有効です。

perl -e 'printf "%.0f\n", 3 ** 333'
760988023132059813486251563646478824265752535077884574263917414498578085812167738721447369281049109603746001743233145041176969930222526036520619613114171654144
于 2014-11-18T17:29:49.837 に答える