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

Monks, would you know if there is a way to convert large numbers to strings without rounding or changes to the digits in the number?

I am trying to match phone numbers for repeating numbers like 99999999999999999999999999 using a simple pattern like /^(\d)(\1)+$/

However I run into truncation issues when the numbers get this large. If I have the number already as a string it is not a problem, however this is not always the case.

I tried the sprintf("%f",$num) but that add decimal places and rounding to the number which does not work.

Best Regards

Ty
  • Comment on Question on converting big numbers to strings without rounding

Replies are listed 'Best First'.
Re: Question on converting big numbers to strings without rounding
by jettero (Monsignor) on Feb 12, 2008 at 13:50 UTC

    usebignum; my $x = 5 ** 512;  print "$x\n";

    I may not understand the problem correctly though. I don't understand why perl wouldn't just treat your long number as a string to begin with. What did you do to make it trunace the number in the first place? sprintf may be a poor choice since it would probably force perl to treat the string as a number...

    -Paul

Re: Question on converting big numbers to strings without rounding
by moritz (Cardinal) on Feb 12, 2008 at 13:53 UTC
    If the numbers are stored in floating point numbers, the problem is not the conversion.

    The numbers are only stored with a certain accuracy, and there's no way to increase that afterwards.

    Phone numbers stored in floating point numbers are worthless, and no conversion magic will change that.

Re: Question on converting big numbers to strings without rounding
by syphilis (Archbishop) on Feb 12, 2008 at 14:05 UTC
    If I have the number already as a string it is not a problem, however this is not always the case

    Can you do something to ensure that the number *is* always a string ? That would surely be the best approach ... if it's feasible. (I think this is what jettero was hinting at.)

    Cheers,
    Rob
Re: Question on converting big numbers to strings without rounding
by apl (Monsignor) on Feb 12, 2008 at 14:13 UTC
    Perl doesn't really differentiate between numbers and strings. Input a string, process a string, don't think of the phone-number as anything but a string.
      I'm pretty sure perl keeps track of the difference somewhat. That's the only way to explain the existence of "looks_like_number" in both Scalar::Util and perlapi. Although it's not "isnumber" and "isstring," it's "looks_like_number," so I could be wrong.

      -Paul

        You are correct, but I was over-simplifying to address the question at hand. There is no reason a 'phone-number' should be treated as a number.

        Perhaps I should simply have said "Just because it looks like a number doesn't mean it shouldn't be treated as a string."

Re: Question on converting big numbers to strings without rounding
by stiller (Friar) on Feb 12, 2008 at 14:58 UTC
    > I tried the sprintf("%f",$num)

    Almost there, but the "%f" says float...

    Try:

    $num = 999999999; print sprintf("%f\n",$num); print sprintf("%d\n",$num);
    cheers

      tmaly has received some excellent advice above and as I understand your contribution, it is an extension of that wisdom. For clarity, for future Seekers, however, to make its relevance explicit (and ramble a bit):

      The essential point (IMO, YMMV) in most of the earlier replies is:

      Don't treat the phone number as a number!

      Granted, it's not clear how tmaly is getting the phone number as a number to begin with, and your sprintf("%d\n",$num); should help, if he has no control over the initial acquisition (if, for example, he's dragging the phone numbers out of a db where the DBA tried to save a few chars by omitting the usual phone number formatting, such as parens around an area code, or dashs or dots to separate the groups).

      But, if he can avoid ever having the phone number treated as a number, he can avoid myriad issues:

      use strict; use warnings; my $string = '99999999999999999999999999'; my $string2 = '9-999-999-999-999-999-999-999-9999'; # see Note 1 below if ( $string =~ /^(\d)(\1|-)+$/ ) { print "\$string might be a phone number: $string \n"; } else { print "$string is NOK \n"; } if ( $string2 =~ /^(\d)(\1|-)+$/ ) { print "\$string2 might be a phone number: $string2 \n"; } else { print "$string2 is NOK \n"; } print "stiller's snippet: \n"; my $num = 999999999; print sprintf("%f\n",$num); print sprintf("%d\n",$num);

      Note the NON-interpolating quoting of the strings; also added alternation on "-" as this is one of the common formatting schemes mentioned above (and is used in $string2. Output looks like this:

      $string might be a phone number: 99999999999999999999999999 # se +e Note 2 $string2 might be a phone number: 9-999-999-999-999-999-999-999-9999 # + also see Note 2 stiller's snippet: 999999999.000000 # a float, as stiller noted, this address's OP's pro +blem, 999999999 # whereas, Perl makes it easy to use this as a strin +g

      1 Interpolating string 2 treats the string as a number and the dashes as subtraction operators
      2 A 26 digit phone number? Isn't this rather longer than one might expect, even allowing for international access codes and an implicit extension? It is in North American useage, but YMMV elsewhere.

        >The essential point (IMO, YMMV) in most of the earlier replies is:
        > Don't treat the phone number as a number!

        That is a very good point, and you are driving it home I hope.

        I should have said that my point was to show that he (at least in this regard) partially introduced the problem himself by formatting the phone number as a float in an attempt to solve his problem, probably only when trying to investigate some odd behavior?

        I did ponder though, on the train home, how the problem ever surfaced, just like you do. In your first string you have forced the number to be a string, putting it in quotes. Removing the quotes though, still yields the same output.

        It would be very interesting if OP posted a simple program to demonstrate what he actually sees.
        regards