Perl-Sensitive Sunglasses PerlMonks

### Subtraction by digit

by zli034 (Monk)
 on Feb 11, 2008 at 08:51 UTC 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";
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 ?

Cheers,
Rob
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
```#!/usr/bin/perl

use strict;
use warnings;

### open(FILEIN, "table.txt"); #numbers table which only has 0 and 1.

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.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://667345]
Approved by Corion
help
Chatterbox?
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
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (118 votes). Check out past polls.

Notices?