Question

Consider the following:

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

My question is simple: How can I disable scientific notation when working with very large numbers? Basically, I'd like to see all the digits dumped to stdout verbatim.

Is this possible?

Was it helpful?

Solution

See Math::BigInt

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

Output:

760988023132059809720425867265032780727896356372077865117010037035791631439306199613044145649378522557935351570949952010001833769302566531786879537190794573523

OTHER TIPS

If you want to do it for all integers in your program, you can just add:

use bigint;

If you only want to do it for some integers, you can create Math::BigInt objects.

There is also bignum and Math::BigNum if you are working with floats.

For very small values see the following code:

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

With numbers that large you may have more digits than the precision used to store the numbers. (Seeing a simple runnable example would have resolved this question).

If you really need to see all 150+ digits, you should use the bigint (for integers), bigrat (for rational numbers) and the bignum (for floating point numbers) modules.

Had the same issue with this code:

#!/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 );
}

The last two lines where printing:

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

Obviously not right, and not realizing the %d conversion was causing the issue, I tried the solution flagged here:

#!/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 );
}

That's when I realized the printf 'd' conversion was causing an issue. Reading up on Math::BigInt it seems to suggest that these numbers are stored as strings inside, so changing to an 's' conversion, fixed the issue:

#!/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 );
}

Now the last two lines printed correctly:

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

But in regards to Karel's answer, which was almost correct IMHO, this could also be done without the use of BigInt (bigint, BigNum, ...) by using the 'f' conversion but with the precision set to '0' to eliminate those decimals:

#!/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 );
}

This also works for the OP's question:

perl -e 'printf "%.0f\n", 3 ** 333'
760988023132059813486251563646478824265752535077884574263917414498578085812167738721447369281049109603746001743233145041176969930222526036520619613114171654144
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top