Reputation: 4679
I Want to do a sub with two big number
my purpose is
1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480
I try with
echo $((1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480))
My result is: 3160661815551241129
but it's not correct.
I can do the similar operation in console chrome and I Have
-1.5642404591095965e+
How can I do this operation in bash?
I tried even with expr
, but without lucky
It's ok to check if a number is greater then another
in shell
echo $((1805334111369276485744644020321551471447190030955050085289>3369574570478873127315415525946742317481702644901195284480))
result: 1
same operation in chrome
1805334111369276485744644020321551471447190030955050085289>3369574570478873127315415525946742317481702644901195284480
result:false
And chrome is right
Upvotes: 3
Views: 759
Reputation: 24812
The ARITHMETIC EVALUATION
section of bash
's manual explains why you get this result with $((...))
:
Evaluation is done in fixed-width integers with no check for overflow
You may be able to use expr
(depending on compile-time options, check @Benjamin W's comment), but you need spaces between the operator and its operands :
$ expr 1805334111369276485744644020321551471447190030955050085289 - 3369574570478873127315415525946742317481702644901195284480
-1564240459109596641570771505625190846034512613946145199191
As @PesaThe mentions you can also use bc
, one of its main features being able to handle arbitrary precision arithmetics :
bc <<< "1805334111369276485744644020321551471447190030955050085289 - 3369574570478873127315415525946742317481702644901195284480"
-1564240459109596641570771505625190846034512613946145199191
Upvotes: 4
Reputation: 785481
Mac OSX awk
can also handle big numbers:
awk 'BEGIN{print 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'
-1.56424045910959651912822682029e+57
Or by using printf
:
awk 'BEGIN{printf "%.5e\n", 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'
-1.56424e+57
On the other hand GNU awk needs -M
switch to support big numbers so use:
gawk -M 'BEGIN{print 1805334111369276485744644020321551471447190030955050085289 - \
3369574570478873127315415525946742317481702644901195284480}'
Upvotes: 1
Reputation: 46853
If you're feeling adventurous you can use that good old dc
(desk calculator, a cute RPN calculator):
dc <<< "1805334111369276485744644020321551471447190030955050085289 3369574570478873127315415525946742317481702644901195284480 - p"
Answer is: -1564240459109596641570771505625190846034512613946145199191
Upvotes: 1
Reputation: 8711
You can use Perl
$ perl -le ' BEGIN { use Math::BigInt; my $x=Math::BigInt->new("1805334111369276485744644020321551471447190030955050085289"); my $y=Math::BigInt->new("3369574570478873127315415525946742317481702644901195284480"); print $x->bsub($y) } '
-1564240459109596641570771505625190846034512613946145199191
$ perl -le ' BEGIN { use Math::BigInt; my $x=Math::BigInt->new("1805334111369276485744644020321551471447190030955050085289"); my $y=Math::BigInt->new("3369574570478873127315415525946742317481702644901195284480"); printf("%g\n",$x->bsub($y)) } '
-1.56424e+57
$
If you want to pass echo output to Perl, then
$ echo "1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480" | perl -ne ' BEGIN { use Math::BigInt } /(\d+)-(\d+)/; $x=Math::BigInt->new($1); $y=Math::BigInt->new($2); printf("%g\n",$x->bsub($y)) '
-1.56424e+57
$
As @PesaThe mentioned you can use bc
also
$ bc <<< "1805334111369276485744644020321551471447190030955050085289-3369574570478873127315415525946742317481702644901195284480"
-1564240459109596641570771505625190846034512613946145199191
$
Upvotes: 1