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

Hi all..

I have peculiar issue in one of my code where Im using sprintf. Please have a look into it and any help on this will be appreciated.

$Val2 = trim(substr($line2,80,11)); print "Value obtained = $Val2\n"; $Val1 = $Val2; print "Value assigned = $Val1\n"; $Val1 = sprintf("%11d", $Val1); print "Value eleven digit = $Val1\n"; $Val1 =~ s/ /0/g; print "Value replaced = $Val1\n";

Output while running this script :

Value obtained = 12143951645 Value assigned = 12143951645 Value eleven digit = -1 Value replaced = 000000000-1

The output "Value eleven digit" printed after sprintf has been printed as -1. Can someone please help me with this issue?

Thanks & Regards,

Sathya V.

Replies are listed 'Best First'.
Re: issue with sprintf..
by LanX (Saint) on Jan 09, 2014 at 10:27 UTC
    %d means signed integer, you are suffering from an overflow problem.

    Since the floating point mantissa is much larger, %f for instance¹ should mitigate the "problem" for some time.

    DB<109> $val=12143951645 => "12143951645" DB<110> sprintf("%11.0f", $val); => "12143951645"

    Only you can tell us how large your numerical ranges are...

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    ¹) see also this post for discussion of string template %s

      Max length of the variable will be zero. Even the variable is of length 5, I want to prefix '0's to make the length 11. Thats my intention.

        so better use sprintf properly, put a leading 0 in the pattern after %.

        Your s/ /0/ substitution is - politely said - less optimal. ;-)

        DB<117> $val=12143 => 12143 DB<118> sprintf("%011.0f", $val); => "00000012143" DB<119> $val=12143951645 => "12143951645" DB<120> sprintf("%011.0f", $val); => "12143951645"

        please read the documentation for more details. =)

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        Or like this:

        $Val2 = '0' x (11-length $Val2) . $Val2 if length $Val2 < 11;

        or this

        $Val2 = substr "00000000000$Val2", -11;
Re: issue with sprintf..
by hdb (Monsignor) on Jan 09, 2014 at 10:28 UTC

    I get four times the same value, so it works for me. Also, it looks as if you want to pad shorter than 11-digit numbers with leading zeroes, this can be achieved by

    $Val1 = sprintf("%011d", $Val1);
      > I get four times the same value,

      Your Perl is compiled for 64 bits?

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        Yes, it is. Could "%u" be helpful?

Re: issue with sprintf.. (%s and %ll$)
by LanX (Saint) on Jan 09, 2014 at 11:07 UTC
    as an alternative to %f you could format integers as strings with %s.

    DB<137> $val=1214395 => 1214395 DB<138> sprintf("%011s", $val); => "00001214395" DB<139> $val="12143951645" => "12143951645" DB<140> sprintf("%011s", $val); => "12143951645"

    So no overflow possible, but don't expect numeric conversions of floats then.

    There is some documentation about manipulating the size of integers, but I couldn't understand how.¹

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    ¹) tl;dr ;-)

    between % and $, but still platform specific

    DB<161> $val="12143951645" => "12143951645" DB<162> sprintf("%ll$11d", $val); => -1