In Perl I know that we can use "$x *= $n" for multiplying x with n. So I mistakenly used "**=" and output seemed to be very high number for very small values of "n". What does that operator do ?
Please do not say that it is just for exponential. It is not. please verify using the syntax I have shown
It is the exponentiation operator:
perl -e 'print 2**3';
prints 8
So, $a **= n is equivalent to $a = $a**n which is equivalent with $a raised to the power n
Related
I tried the following in a Perl script:
$b = 19999999999999999 % 10000000000000000;
print "$b\n";
It incorrectly outputted 0.
Then I found an answer saying to use bignum:
use bignum;
$b = 19999999999999999 % 10000000000000000;
print "$b\n";
It correctly outputted 9999999999999999.
But bignum just converts all integer constants into a Math::BigInt. So I tried the following which should be the same as using bignum:
use Math::BigInt;
$b = Math::BigInt->new(19999999999999999) % Math::BigInt->new(10000000000000000);
print "$b\n";
But that incorrectly outputted 0. Am I doing something wrong with Math::BigInt?
You're still using native Perl numbers first and then converting them to Math::BigInt objects. Try this instead:
my $x = Math::BigInt->new('19999999999999999') % Math::BigInt->new('10000000000000000');
Quoting from perldoc Math::BigInt:
Input given as scalar numbers might lose precision. Quote your input to ensure that no digits are lost:
$x = Math::BigInt->new( 56789012345678901234 ); # bad
$x = Math::BigInt->new('56789012345678901234'); # good
(Also, don't use $b outside of sort and similar routines.)
In my script i am dealing with binary value and i need to replace 0->1 and 1->0 at one place.
example :
input digit = 10101001
output digit = 01010110
I tried $string =~ s/1/0/; and reverse function but that is getting fail to give me correct out put.
can some one help me out.
Use tr:
my $str = '10101001';
$s =~ tr/01/10/;
print "$s\n";
Outputs:
01010110
If your input string has only those two possibilities 0 and 1, then you can use substitution in a multi-stage approach:
$str =~ s/1/x/g; # all 1's to x
$str =~ s/0/1/g; # all 0's to 1
$str =~ s/x/0/g; # all x's to 0
This is not a bad option for languages that only provide substitutions, but Perl also has an atomic translation feature:
$str =~ tr/01/10/;
which will work just as well (better, really, since it's less code and probably less passes over the data).
You could also go mathy on this and use the bitwise XOR operator ^...
my $input = '10101001';
my $binval = oct( '0b'.$input );
my $result = $binval ^ 0b11111111;
printf "%08b\n", $result;
...which will also give you 01010110.
This of course has the downside of being dependent on the length of the bit input string. The given solution only works for 8-bit values. It wouldn't be hard to generalize for any number of bits, though.
To incorporate Lưu Vĩnh Phúc's comment - you can also use the bitwise NOT operator ~. Again, the implementation is dependent on the number of bits as you need to truncate the result:
my $input = '10101001';
my $binval = oct( '0b'.$input );
print substr( sprintf ( '%b', ~$binval ), -8 )."\n";
So I have this bit of code that does not work:
print $userInput."\n" x $userInput2; #$userInput = string & $userInput2 is a integer
It prints it out once fine if the number is over 0 of course, but it doesn't print out the rest if the number is greater than 1. I come from a java background and I assume that it does the concatenation first, then the result will be what will multiply itself with the x operator. But of course that does not happen. Now it works when I do the following:
$userInput .= "\n";
print $userInput x $userInput2;
I am new to Perl so I'd like to understand exactly what goes on with chaining, and if I can even do so.
You're asking about operator precedence. ("Chaining" usually refers to chaining of method calls, e.g. $obj->foo->bar->baz.)
The Perl documentation page perlop starts off with a list of all the operators in order of precedence level. x has the same precedence as other multiplication operators, and . has the same precedence as other addition operators, so of course x is evaluated first. (i.e., it "has higher precedence" or "binds more tightly".)
As in Java you can resolve this with parentheses:
print(($userInput . "\n") x $userInput2);
Note that you need two pairs of parentheses here. If you'd only used the inner parentheses, Perl would treat them as indicating the arguments to print, like this:
# THIS DOESN'T WORK
print($userInput . "\n") x $userInput2;
This would print the string once, then duplicate print's return value some number of times. Putting space before the ( doesn't help since whitespace is generally optional and ignored. In a way, this is another form of operator precedence: function calls bind more tightly than anything else.
If you really hate having more parentheses than strictly necessary, you can defeat Perl with the unary + operator:
print +($userInput . "\n") x $userInput2;
This separates the print from the (, so Perl knows the rest of the line is a single expression. Unary + has no effect whatsoever; its primary use is exactly this sort of situation.
This is due to precedence of . (concatenation) operator being less than the x operator. So it ends up with:
use strict;
use warnings;
my $userInput = "line";
my $userInput2 = 2;
print $userInput.("\n" x $userInput2);
And outputs:
line[newline]
[newline]
This is what you want:
print (($userInput."\n") x $userInput2);
This prints out:
line
line
As has already been mentioned, this is a precedence issue, in that the repetition operator x has higher precedence than the concatenation operator .. However, that is not all that's going on here, and also, the issue itself comes from a bad solution.
First off, when you say
print (($foo . "\n") x $count);
What you are doing is changing the context of the repetition operator to list context.
(LIST) x $count
The above statement really means this (if $count == 3):
print ( $foo . "\n", $foo . "\n", $foo . "\n" ); # list with 3 elements
From perldoc perlop:
Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context, if the left operand is enclosed in parentheses or is a list formed by qw/STRING/, it repeats the list. If the right operand is zero or negative, it returns an empty string or an empty list, depending on the context.
The solution works as intended because print takes list arguments. However, if you had something else that takes scalar arguments, such as a subroutine:
foo(("text" . "\n") x 3);
sub foo {
# #_ is now the list ("text\n", "text\n", "text\n");
my ($string) = #_; # error enters here
# $string is now "text\n"
}
This is a subtle difference which might not always give the desired result.
A better solution for this particular case is to not use the concatenation operator at all, because it is redundant:
print "$foo\n" x $count;
Or even use more mundane methods:
for (0 .. $count) {
print "$foo\n";
}
Or
use feature 'say'
...
say $foo for 0 .. $count;
i have the following problem:
I have a number of values x and I need to compute x^e (e being euler's number).
I do this:
$x = $x ** exp(1);
This results in "nan" for all of my test cases.
However if I print the values of $x before I do this and then take one and change above line to this:
$x = -12.4061063212051 ** exp(1);
it results in perfectly fine numbers.
Can anyone point out what I am doing wrong here?
Thanks
PS: Maybe the error hides somewhere else, so here is how i compute $x:
$y = #some float value taken from the output string of another program
$x = ($y/(303 * 0.0019872041));
print $x; #prints number
$x = $x ** exp(1);
print $x; #prints "nan"
It's all about operator precedence:
$x = -12.4061063212051 ** exp(1);
is really
$x = - (12.4061063212051 ** exp(1));
as seen using
$ perl -MO=Deparse,-p -e'$x = -12.4061063212051 ** $e'
($x = (-(12.4061063212051 ** $e)));
-e syntax OK
Which is fine.
If you try the following it will also fail just as your program:
$x = (- 12.4061063212051) ** exp(1);
And it should, there is no real number that meets this criteria.
Let's make things a bit easier for the moment, and suppose that we were taking $x**2.5. Well, since 2.5==5.0/2.0, we have $x**2.5==$x**(5.0/2.0)==($x**0.5)**5.0. Or, in other words, $x**2.5 is the same thing as the fifth power of sqrt($x).
Since computers tend to only deal with real numbers by default, what do you think would happen if, say $x==-1?
Yeah....now, what if $x<0$ and we wanted to take $x**exp(1) (the decimal approximation that Perl uses for exp(1) is 2.71828182845905)?
I have input that looks like
5 X
8 Y
3 Z
9 X
I want output that sums the numerical values for each 'tag'; e.g.
14 X
8 Y
3 Z
Wondering if there is a slick one liner I can use (along the lines of the ones for summing a list of integers using awk).
Something like this should do the trick:
perl -ne '$table{$2} += $1 if /(\d+)\s+(.+)/; END {print "$table{$_} $_\n" for keys %table}'
or to use auto-splitting:
perl -ane '$table{$F[1] or next} += $F[0]; END {print "$table{$_} $_\n" for keys %table}'
As slick as I can make it:
perl -alne 'END{print"$X{$_} $_"for sort{$X{$b}<=>$X{$a}}keys%X}$X{$F[1]}+=$F[0]'
Tried to make it as little obfuscated as possible :)
Sorts output by 'tag'.
perl -alne '$counts{$F[1]} += $F[0]; END { print "$counts{$_} $_" for sort(keys %counts) }'
Output in random order
perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for keys%t'
alphabetically sorted by tag
perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for sort keys%t'
sorted by value
perl -alne'$t{$F[1]}+=$F[0]}{print"$t{$_} $_"for sort{$t{$b}<=>$t{$a}}keys%t'
gawk "{count[$2]+=$1}END{for(i in count)print count[i],i}" 1.t