Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Subtracting Stringified Negative Numbers

by monkfan (Curate)
on Jun 22, 2007 at 04:07 UTC ( #622704=perlquestion: print w/ replies, xml ) Need Help??
monkfan has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I was trying to substract these two values:
my $n1 = '-933'; my $n2 = '-1039'; my $dif = $n1 - $n2;
In print Dumper for "n1" and "n2" looks like this:
$VAR1 = '-933'; $VAR1 = '-1039';
But how come when I substracted them, they give:
Argument "^\-933" isn't numeric in subtraction (-) at mycode.pl line 1 +15. Argument "^\-1039" isn't numeric in subtraction (-) at mycode.pl line +115.
Where the "$dif" value is printed as 0. How can I overcome this problem?

update: Here is some additional context. Earlier, $n1 and $n2 was obtained from this step:
my $some_string = "0,-933"; my ($id1,$n1) = split(",",$some_string);
And my Perl version is:
This is perl, v5.8.5 built for i386-linux-thread-multi

Regards,
Edward

Comment on Subtracting Stringified Negative Numbers
Select or Download Code
Re: Subtracting Stringified Negative Numbers
by naikonta (Curate) on Jun 22, 2007 at 04:23 UTC
    That's really strange. Are you sure that $n1 and $n2 are assigned with literal value as you do, and not from any external resources or inputs?

    Update: Following your update, now we know that $n1 is splitted out from $some_string. But, where the heck this $some_string came from? It's the ultimate source of the data you need to tell so we know how is the data originally or initially the first time it arrives to the perl interpreter or your script. Don't emulate by literally assinging it to a variable if that's not actually the case since we'll just get nowhere.

    $ cat diff.pl use strict; use warnings; my $n1 = '-933'; # the same result my $n2 = '-1039'; # without quotes my $diff = $n1 - $n2; print "diff: $diff\n"; $ perl diff.pl diff: 106 $ perl -V Summary of my perl5 (revision 5 version 8 subversion 8) configuration: Platform: osname=linux, osvers=2.6.9-22.18.bz155725.elsmp, archname=i386-lin +ux-thread-multi uname='linux hs20-bc1-6.build.redhat.com 2.6.9-22.18.bz155725.elsm +p #1 smp thu nov 17 15:34:08 est 2005 i686 i686 i386 gnulinux '

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: Subtracting Stringified Negative Numbers
by Zaxo (Archbishop) on Jun 22, 2007 at 04:23 UTC

    It works for me,

    $ perl -w -e'my$n1="-933";my$n2="-1039";my$dif=$n1-$n2;print $dif,$/' 106 $
    Your error messages say directly that you have more characters than minus, plus and digits in your argument variables. The presence of "^\" at the start of each string is causing the problem, making the strings not look like numbers.

    Figure out how the spurious characters are getting in and you'll find the solution.

    After Compline,
    Zaxo

      And this reminds me of another reason why I don't use Data::Dumper. It defaults to being "efficient" and so doesn't actually 'dump' the variable contents, in an effort to avoid the arduous task of escaping all those weird characters. You have to go out of your way to tell Data::Dumper to "useqq" for it to actually dump strings in a fool-proof manner.

      > perl -del # ... DB<4> print Dumper("\c\\-10") $VAR1 = '-10'; DB<5> print Data::Dumper->new(["\c\\-10"])->Useqq(1)->Dump() $VAR1 = "\34-10"; DB<6>

      The unescaped CTRL-\ removed from the above output as how it would be displayed would depend on several things and it didn't even remain a CTRL-\ after being copy-n-pasted into the browser and converted to Latin-1 etc. anyway.

      Update: Oh, I thought Zaxo had noted what "^\" represents but I see he didn't so, to be very clear, "^\" is how perl is safely dumping a single CTRL-\ ("\c\\") character in that warning, which is why my example code looks like it does. No, I didn't realize this when first viewing the warning.

      - tye        

        You are right, tye. Following your suggestion, and by doing this:
        my $some_string = "0,-933"; $Data::Dumper::Useqq = 1; print Dumper ($some_string) ; my ($id1,$n1) = split(",",$some_string); #then do things with $n1 and $n2.
        It gives:
        $VAR1 = "0,\34-933";
        So my questions are:
        • How can this \34 comes, in the first place? Can we avoid that?
          My development is always under Linux/Unix platform. And those variable values are read from a file.
        • How to remove this \34 character from $VAR?

        Regards,
        Edward
Re: Subtracting Stringified Negative Numbers
by agianni (Hermit) on Jun 22, 2007 at 04:28 UTC

    Hmmm... when I tried your code it worked just fine and $dif had the value of 106. What version of Perl are you using? What is the actual context of the code?

    Not knowing the context, you might consider doing something like:

    my $dif = ( int $n1 ) - ( int $n2 );
    to force the strings into integers. But I'm thinking there's something else going on. Additional context would definitely help.

    perl -e 'split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(joi +n(q{},map{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79 +*36997,13*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));'
Re: Subtracting Stringified Negative Numbers
by garu (Scribe) on Jun 22, 2007 at 04:34 UTC
    What is your perl version?

    If I run your program as:

    my $n1 = '-933'; my $n2 = '-1039'; my $dif = $n1 - $n2; print $dif . "\n";

    I get "106" as an output, which seems to be what you want.

    Btw, here I have:

    C:> perl -v This is perl, v5.8.8 built for MSWin32-x86-multi-thread (with 50 registered patches, see perl -V for more detail) Binary build 820 [274739] provided by ActiveState
Re: Subtracting Stringified Negative Numbers
by Anonymous Monk on Jun 22, 2007 at 04:40 UTC
    perlnumber - semantics of numbers and numeric operations in Perl
Re: Subtracting Stringified Negative Numbers
by GrandFather (Cardinal) on Jun 22, 2007 at 04:55 UTC

    Perhaps you could show us an actual runnable sample that demonstrates the problem? You could start by modifying the following to the point where it doesn't work any more:

    use strict; use warnings; my $some_string = "0,-933"; my ($id1, $n1) = split(",",$some_string); my $dif = $id1 - $n1; print $dif;

    Prints:

    933

    DWIM is Perl's answer to Gödel
Re: Subtracting Stringified Negative Numbers
by graff (Chancellor) on Jun 22, 2007 at 04:58 UTC
    Given that you showed us those error messages:
    Argument "^\-933" isn't numeric in subtraction (-) at mycode.pl line 1 +15. Argument "^\-1039" isn't numeric in subtraction (-) at mycode.pl line +115.
    I'm wondering why you didn't show us the actual line 115 from the script that produced the error, along with the previous lines where values were assigned to the two variables involved (as well as the earlier line where a value is assigned to the variable that is being split).

    Since the error message indicates that the values include initial caret and backslash characters ("^\"), my first guess would be that something odd is happening when assigning a value to the string that is being split on "," -- or something is altering the two values after the split -- involving regular expression operations.

    Show us more of the actual code that caused the error -- in fact, see if you can construct a minimal self-contained script that includes the relevant value assignments, the split and the subtraction, and generates the error.

    As others have pointed out, the "boiled down" information you've shown so far would not cause this error.

Re: Subtracting Stringified Negative Numbers
by BrowserUk (Pope) on Jun 22, 2007 at 05:39 UTC

    Your strings having a leading character, ascii 28 (also known as the field separator). I can reproduce your error messages and results as follows:

    $n1 = "\x1c-933"; ## hex( 1c ) == 28 == ^\ == Field separator $n2 = "\x1c-1093"; print $n1 - $n2;; Argument "^\-1093" isn't numeric in subtraction (-) at (eval 6) line 1 Argument "^\-933" isn't numeric in subtraction (-) at (eval 6) line 1 0

    That doesn't explain how those characters are getting into your data, but it will give you something to look for. You could try dumping the string prior to spliting using unpack:

    print unpack 'C*', $the_string;

    Is this data being read from a file or a device?

    Is there any chance that the data is getting the unicode bit set?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Subtracting Stringified Negative Numbers
by Moron (Curate) on Jun 22, 2007 at 12:55 UTC
    The '^' (carat) at the beginning causes the error. All else that follows never makes it to the parser.
    __________________________________________________________________________________

    ^M Free your mind!

      Heh, you might want to read the thread (or even the entire original node) since there are no carets (nor even any carats, at least according to my scale) in these strings. Just FYI. :)

      - tye        

        Posts on this site occur in chronological order. The OP reveals that the error message blames '^\'. My mistake was simply that I didn't realise the parser intended this as a representation of ctrl-\ - a finding published later than my post. But obviously from your comment, you didn't know that either or didn't draw the correct inference.
        __________________________________________________________________________________

        ^M Free your mind!

Re: Subtracting Stringified Negative Numbers
by FunkyMonk (Canon) on Jun 22, 2007 at 16:33 UTC
    You haven't been doing anything like this, have you?
    $h{1, 2} = "hello";
    This creates a key consisting of three characters: "1", $SUBSEP and "2". $SUBSEP has a default octal value of 034 (aka Ctrl-\).

    my %h; $h{1, 2} = "hello"; $Data::Dumper::Useqq = 1; print Dumper \%h;

    From perlvar:

    $SUBSCRIPT_SEPARATOR $SUBSEP $; The subscript separator for multidimensional array emulation. +If you refer to a hash element as $foo{$a,$b,$c} it really means $foo{join($;, $a, $b, $c)}
      That's exactly what I did. Thanks so much for pointing that out!
      FunkyMonk+++

      Regards,
      Edward

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://622704]
Approved by naikonta
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (10)
As of 2014-09-02 00:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (18 votes), past polls