Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

negative numbers when doing multiplications?

by BhariD (Sexton)
on Mar 26, 2010 at 13:22 UTC ( [id://831146]=perlquestion: print w/replies, xml ) Need Help??

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

I am doing a multiplication

#!/usr/bin/perl use strict; use warnings; use integer; my %iupac_dgn; my @iupac_code=('M','R','W','S','Y','K','V','H','D','B','N'); my @iupac_den=('2','2','2','2','2','2','3','3','3','3','4'); @iupac_dgn{@iupac_code}=@iupac_den; my $string = 'GGNMDNNSNNNNDBNVWVSMNNHYNBNG'; my @residues = split(//, $string); my degeneracy = 1; foreach my $residues(@residues){ if(grep($_=~m/^$residues$/, keys %iupac_dgn)){ my $factor = $iupac_dgn{$residues}; $degeneracy = ($factor * $degeneracy); } } printf PRIMER_PAIRS "%28s, %30d", $string, $degeneracy;

for this particular string, it gives me a number with '-' in front '-1073741824'. am I doing something wrong here.. can anyone please help me

Thanks!

Replies are listed 'Best First'.
Re: negative numbers when doing multiplications?
by moritz (Cardinal) on Mar 26, 2010 at 13:30 UTC
    With some small fixes to your code I do get a (large) positive number, namely 2348273369088 (I'm on a 64bit system, if that matters).

    Things you can try: use bigint (see bigint), and use ordinary print instead of printf() for debugging.

    Finally your hash access is unnecessary complicated - instead of the grep you can just access $iupac_dgn{$residues} directly.

    The simplified code looks like this:

    #!/usr/bin/perl use strict; use warnings; use integer; my %iupac_dgn; my @iupac_code = ('M','R','W','S','Y','K','V','H','D','B','N'); my @iupac_den = ('2','2','2','2','2','2','3','3','3','3','4'); @iupac_dgn{@iupac_code}=@iupac_den; my $string = 'GGNMDNNSNNNNDBNVWVSMNNHYNBNG'; my @residues = split(//, $string); my $degeneracy = 1; foreach my $residues(@residues){ $degeneracy *= $iupac_dgn{$residues} || 1; } printf "%28s, %30s\n", $string, $degeneracy;
    Perl 6 - links to (nearly) everything that is Perl 6.

      If you are on a 32-bit system, you must use Math::BigInt. The following returns 2348273369088.

      #!/usr/bin/perl use strict; use warnings; use integer; use Math::BigInt; my %iupac_dgn; my @iupac_code = ('M','R','W','S','Y','K','V','H','D','B','N'); my @iupac_den = ('2','2','2','2','2','2','3','3','3','3','4'); @iupac_dgn{@iupac_code}=@iupac_den; my $string = 'GGNMDNNSNNNNDBNVWVSMNNHYNBNG'; my @residues = split(//, $string); my $degeneracy = Math::BigInt->new( 1 ); foreach my $residues(@residues){ $degeneracy *= $iupac_dgn{$residues} || 1; } printf "%28s, %30s\n", $string, $degeneracy;

      Update: I will concur with Tye as long as the result is less than 2 ** 49 on a 32b machine/implementation. Thanks.

      Good Luck. -c

        If you are on a 32-bit system, you must use Math::BigInt.

        Don't be foolish. :) Just don't use the stupid integer.pm module:

        #!/usr/bin/perl use strict; use warnings; # use integer; my %iupac_dgn; my @iupac_code=('M','R','W','S','Y','K','V','H','D','B','N'); my @iupac_den=('2','2','2','2','2','2','3','3','3','3','4'); @iupac_dgn{@iupac_code}=@iupac_den; my $string = 'GGNMDNNSNNNNDBNVWVSMNNHYNBNG'; my @residues = split( //, $string ); my $degeneracy = 1; foreach my $residues( @residues ) { if( grep( m/^$residues$/, keys %iupac_dgn ) ) { my $factor = $iupac_dgn{$residues}; $degeneracy = ($factor * $degeneracy); } } printf "%28s, %30d", $string, $degeneracy; __END__ GGNMDNNSNNNNDBNVWVSMNNHYNBNG, 2348273369088

        - tye        

Re: negative numbers when doing multiplications?
by almut (Canon) on Mar 26, 2010 at 14:29 UTC

    You apparently have a perl binary that only supports 32-bit integers.  And the value you compute (2348273369088) is much larger than 32 bits can hold. Represented as binary, it is:

    10_00100010_11000000_00000000_00000000_00000000

    So, it gets truncated

    11000000_00000000_00000000_00000000

    and as the leftmost (most significant) bit happens to be 1, and you used %d (= signed int) in printf, it is interpreted as a negative value (see Two's Complement). Effectively the same as

    printf "%d", 0b11000000_00000000_00000000_00000000 - 2**32; # -1073 +741824

    with a perl that supports ints larger than 32 bit.

Re: negative numbers when doing multiplications?
by Anonymous Monk on Mar 26, 2010 at 13:27 UTC

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-19 17:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found