Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Subtraction by digit

by zli034 (Monk)
on Feb 11, 2008 at 08:51 UTC ( #667345=perlquestion: print w/replies, xml ) Need Help??
zli034 has asked for the wisdom of the Perl Monks concerning the following question:

Say there are two integers of scalar. I want to substract them by digits.

like this: 1,2,3,4,5,6 - 2,9,8,4,7,6 = -1,-7,-5,0,-2,0

When I tried it, I split the two scalars in to 2 arrays of single digits, then performed digit substract. However the results are float numbers.

Appreciate any good suggestions.

Update ###################################

open(FILEIN, "table.txt"); #numbers table which only has 0 and 1. open FILEOUT, ">>data.txt"; #opens data.txt in read-mode my $input="01110011001111100010111101011111000100110000000000000001111 +111101101111101011010"; my @seed = split //; while(<FILEIN>){ #reads line by line from FILE which + is the filehandle for data.txt #chomp; my $temp=''; my @ca = split //; #$_ =~ tr/ /\n/; my $count = 0; foreach my $digit (@ca){ @seed[$count] = @seed[$count] - $_; $count++; } print FILEOUT "@seed\n"; #shows you what we have read } close FILEIN; close FILEOUT;

Replies are listed 'Best First'.
Re: Subtraction by digit
by hipowls (Curate) on Feb 11, 2008 at 09:00 UTC

    How did you do it? Unless you post code we can't tell what went wrong. Works fine for me

    my @one = split /,/, '1,2,3,4,5,6'; my @two = split /,/, '2,9,8,4,7,6'; my @result; for my $i ( 0 .. $#one ) { push @result, $one[$i] - $two[$i]; } my $result = join ',', @result; print $result, "\n"; __END__ -1,-7,-5,0,-2,0

    Update: As suggested by j1n3l0

    use List::MoreUtils qw(pairwise); my @one = split /,/, '1,2,3,4,5,6'; my @two = split /,/, '2,9,8,4,7,6'; our ($a, $b); # keep warnings happy my $result = join ',', pairwise { $a - $b } @one, @two;

Re: Subtraction by digit
by ysth (Canon) on Feb 11, 2008 at 08:56 UTC
    Show the code you tried? What do you mean, "the results are float numbers"? Showing both what you got and what you expected would help people understand you better.
Re: Subtraction by digit
by j1n3l0 (Friar) on Feb 11, 2008 at 10:24 UTC
    You could try a solution like this post or you could investigate PDL for their matrix manipulations.

    Smoothie, smoothie, hundre prosent naturlig!

      Thanks, just reread the doco for List::MoreUtils. I really must remember to do that anytime there is a list processing problem that doesn't quite fit standard techniques

Re: Subtraction by digit
by moklevat (Priest) on Feb 11, 2008 at 15:18 UTC
    The A trivial PDL solution would be:
    use strict; use warnings; use PDL; my $first = pdl qw/1 2 3 4 5 6/; my $second = pdl qw/2 9 8 4 7 6/; my $result = $first - $second; print "$result\n";
Re: Subtraction by digit
by syphilis (Chancellor) on Feb 11, 2008 at 09:13 UTC
    How do you arrive at the conclusion that they are "float numbers", and why does it matter ?

Re: Subtraction by digit
by eric256 (Parson) on Feb 11, 2008 at 17:11 UTC

    Some code would have been nice, but you can try push( @c, shift(@a) - shift(@b)) while (@a and @b); It is destructive, but @c will contain the results when it is done and it.

    or a non-descructive version  $c[$_] =  $a[$_] - $b[$_] for  0 ..  ($#a <  $#b ? $#a : $#b);, but I think the first is easier to read. ;)

    Updated thanks to some comments from ysth regarding precedence and a typo )

    Eric Hodges
Re: Subtraction by digit
by graff (Chancellor) on Feb 12, 2008 at 07:25 UTC
    Thank you for updating the post with your code. Here's a modified version that might behave more to your liking (but I'm not sure). Comments that I've added start with "###":
    #!/usr/bin/perl use strict; use warnings; ### open(FILEIN, "table.txt"); #numbers table which only has 0 and 1. ### let's read from __DATA__ instead (try adding your own DATA...) open FILEOUT, ">>data.txt" or die "data.txt: $!\n"; ### opens data.txt in output/append mode my @seed = split //, "01110011001111100010111101011111000100110"; my $expected = scalar @seed; while (<DATA>) { ### reads line by line from DATA which is provided b +elow chomp; ### you do want to chomp the input if ( ! /^[01]+$/ ) { warn "input line $. has characters other than 0 and 1\n"; next; } my $length = length(); if ( $length != @seed ) { warn "input line $. has $length digits instead of $expected\n" +; } my $count = 0; for my $digit ( split // ) { $seed[$count++] -= $digit; } print FILEOUT "@seed\n"; #shows you what we have read } ### close FILEIN; close FILEOUT; __DATA__ 01110011001111100010111101011111000100110 01110011001111100010111101011111000100110 1110011001111100010111101011111000100110 0011100110011111000101111010111110001001101 012345 xyz
    Compared to what you posted, this version:

    • uses a shorter sample string for creating @seed (just for the sake of easier posting)

    • actually puts something into @seed -- your version does not: you assign a string to "$input", but this variable is not used anywhere else

    • includes sample data with the script, so that it can be run without having to open an external input file (which you did not provide); the sample data consists of a copy of the "seed" string, along with a few simple variations to test things out.

    • includes some sanity checks on the input: (a) reject a line that contains anything other than 0's and 1's (but your initial example used other digits, so maybe you don't want this?), and (b) issue warnings for lines with unexpected lengths (but go ahead and use them)

    • avoids the use of unnecessary variables and the  @seed[$count] mistake, and includes "use strict" and "use warnings" (which pointed out that mistake)

    When I ran it, everything in the output was integers (no fractional numbers with decimal points). Of course. since values are being subtracted from the seed array, (which started with 0's and 1's), the results end up as negative decimal values (e.g. if seed starts with "0" in a given position, and the first two lines of input have "1" in that position, you get "-2").

    If you were hoping to get binary digit results, what do you expect "0 - 1 - 1" to produce? Maybe you want some sort of bitwise operation instead of integer subtraction? Check out perlop (look for "bitwise"), as well as the vec, pack and unpack functions. Hint: try this:

    #!/usr/bin/perl -l $a="0101"; $b="1110"; print "$a & $b = " . ($a & $b); print "$a | $b = " . ($a | $b); print "$a ^ $b = " .(($a ^ $b) | "0000"); # this one is a little trick +y __OUTPUT__ 0101 & 1110 = 0100 0101 | 1110 = 1111 0101 ^ 1110 = 1011

    Can you demonstrate the problem you mentioned (getting "float" numbers) using some sample data of your own? If so, please show us that data.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://667345]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2018-06-21 18:40 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (118 votes). Check out past polls.