toadi has asked for the wisdom of the Perl Monks concerning the following question:

Here's folowing problem:
my $pad_len_sum = my $som_rekening = "2147483648"; my $pad_len_sum = 15; my $padded_som = sprintf("%0${pad_len}d", $sum); print "PADDED SOM: $padded_sum - $sum\n";
I solved it the following way:
my $som_rekening = "2147483648"; my $i = 15-length($som_rekening); $i = 0 if( $i < 0 ); my $padded_som = "0"x$i.$som_rekening; print "PADDED SOM: $padded_som - $som_rekening\n";
Does this show me that I need to use inline C or something if I want to trust adding numbers together??

Or is there a better way to get around this problem??

--
My opinions may have changed,
but not the fact that I am right

Replies are listed 'Best First'.
Re: perls long number problem
by davorg (Chancellor) on Dec 10, 2001 at 16:21 UTC

    You first example is very confused - you try to use a number of uninitialised variables. By changing it to:

    my $som_rekening = "2147483648"; my $pad_len_sum = 15; my $padded_som = sprintf("%0${pad_len_sum}s", $som_rekening); print "PADDED SOM: $padded_som - $som_rekening\n";

    I believe I've now worked out what the problem is - it prints out:

    PADDED SOM: 000002147483647 - 2147483648

    It looks like you're running up against the limits of Perl's numeric accuracy. You might find that that Math::BigInt module will allow you to deal with larger numbers.

    If, on the other hand, you are formatting this number to display it in some way, why not just treat it as a string like this:

    my $som_rekening = "2147483648"; my $pad_len_sum = 15; my $padded_som = sprintf("%0${pad_len_sum}s", $som_rekening); print "PADDED SOM: $padded_som - $som_rekening\n";

    This outputs:

    PADDED SOM: 000002147483648 - 2147483648
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Yep that was what I wanted to show, Perl just couldn't handle the long numbers. I wanted to see if there's another solution than trying to handle numbers as string...

      I made some typing mistakes in the code, Sorry for that.

      --
      My opinions may have changed,
      but not the fact that I am right

        Perl can only handle integers up to the size it was configured with. But it can handle numbers larger that that. Try your example with

        sprintf("%{$len}.0f",$number);

        And you will see the number just fine. This is because perl uses doubles to hold real numbers, which can typically hold numbers of more bits. On most machines perl runs, integers are 32 bits and doubles use 53 bits for the mantissa.

        So yes, perl can handle larger numbers without strings, providing you don't convert them to integers

Re: perls long number problem
by rob_au (Abbot) on Dec 10, 2001 at 16:08 UTC
    I'm not exactly sure what it is that you have been wanting to perform with your code, but why aren't you using perlfunc:sprintf ? This would simplify your code greatly. eg.

    my $som_rekening = "2147483648"; my $padded_som = sprintf("%15d", $som_rekening);

    This is where I'm not sure what you are wanting to achieve with the last line? Maybe you could paste a little more of your code outlining what it is you are wanting to achieve?

     

    Update : - If its the numeric accuracy of Perl that you running up against as davorg suggests, then I would most certainly concur with his decision to look at Math::BigInt

     

    perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

Re: perls long number problem
by sparkyichi (Deacon) on Dec 11, 2001 at 22:44 UTC
    I have not had problems with Perl handling large numbers. I had written a program for multiplying very large prime numbers together (a bit of cracking). The results were up to 12 digits long.
    open (FILE, 'pout.txt') || die "Could not open output:\n $!\n"; $i = 0; while (<FILE>){ chomp($_); ($key, $prime) =split (/ /, $_); push (@prime, $prime); } $nop = @prime; print "$nop primes found.\n"; $i = 0; until ( $i == 1) { print "Enter First Key\: "; $key1 = <STDIN>; chomp ($key1); print "Enter Second Key\: "; $key2 = <STDIN>; chomp ($key2); $total = (@prime[$key1] * @prime[$key2]); print "@prime[$key1] times @prime[$key2] is $total\n"; }
    This code takes my file with a key ordered list of prime numbers and pushes each prime onto @prime. It then asks the user to specify to keys to multiply together and prints the result. I was about to handle some very large numbers with this.

    Sparky
      If you turned on warnings you would get several warnings about that code. (In particular centered about the fact that you don't know how to correctly access an element of an array.)

      Also note that 12 digits, your preconceptions notwithstanding, is not a large number. Try 10 times that many digits and see if you don't discover what Perl's large number limits look like...