Arithmetic with variable [duplicate] - bash

This question already has answers here:
How do I use floating-point arithmetic in bash?
(23 answers)
Closed 8 years ago.
I need to perform some arithemic with bash.It goes like this
VariableA = (VariableB-VariableC) / 60
Variable A should be approximated to 2 decimal places
I don't know which one of these is the right answer(Don't have a linux server at hand atm to test)
VariableA = $((VariableB-VariableC)/60)
VariableA = $(((VariableB-VariableC)/))/60)
It would be nice if someone could also help me out about how to round the VariableA to 2 decimal places without using third party tools like bc

The bash itself can compute only integer values, so if you need to use a fixed number of decimals, you can shift your decimal point (it's like computing in cents instead of dollars or euros). Then only at the output you need to make sure there's a . before the last two digits of your number:
a=800
b=300
result=$((a*100/b)) # factor 100 because of division!
echo "${result:0:-2}.${result: -2}"
will print 2.66.
If you want to make computations in floating points, you should use a tool like bc to do that for you:
bc <<<'scale=2; 8.00/3.00'
will print out 2.66.

Related

How to round to 1 decimal in bash?

I am trying my first script on bash and I am not able to round (not truncate).
So, I am getting 55.08 and I would like to convert it to 55.1
promedio=$(echo "scale=2; $lineas/($dias*24)" | bc)
Note that I am currently using scale=2 because scale=1 produces 55.0.
Thank you all :)
This is not so much a bash question as a bc one, but bc doesn’t round. The easiest approach is probably just to add .05 after the division, then set scale to 1 and divide by 1 to force truncation.
You can do that by using a variable inside bc to hold the unrounded result:
promedio=$(bc <<<"scale=2; p=$lineas/($dias*24); scale=1; (p+0.05)/1")
Or you could do it all in one go by throwing in an extra multiplication by 10, rounding at that magnitude, and then dividing back down:
promedio=$(bc <<<"scale=1; (10*$lineas/($dias*24)+0.5)/10")

Ruby and mathematical problems [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 4 years ago.
I was trying to solve a mathematical problem:
37.9 - 6.05
Ruby gives me:
37.9 - 6.05
#=> 31.849999999999998
37.90 - 6.05
#=> 31.849999999999998
37.90 + 6.05
#=> 43.949999999999996
Why am I getting this?
In a nutshell, computers have a problem working with real numbers and use
floating point representation to deal with them. Much in the same way you can only represent 256 numbers with 8 bits for natural numbers, you can only represent a fixed amount of numbers with 64 bits for real numbers. For more details on this, read this http://floating-point-gui.de/ or google for "floating point arithmetic".
How should i deal with that?
Never store currency values in floating point variables. Use BigDecimal or do your calculations in cents using only integer numbers.
use round to round your floats to a user friendly length. Rounding errors will occur, especially when adding up a lot of floats.
In SQL systems use decimal data type, or use integers and divide them by a constant factor in the UI (say you need 3 decimal digits, you could store 1234 as integer and display 1.234.

Bash - how to sort negative values? [duplicate]

This question already has answers here:
Linux sort doesn't work with negative float numbers
(3 answers)
Closed 6 years ago.
is there a way to sort negative numbers with sort in bash ? I have sin written out
...
0.250109
0.188852
0.126850
0.064349
0.001593
-0.061168
-0.123689
-0.185722
-0.247023
-0.307349
...
and the problem is when I run sort on it, it just sorts it by values - regardless of the minus in front of some values. Is there a way to fix it ? Thanks
Use sort -g (--general-numeric-sort), not sort -n (--numeric-sort).
See sort Invocation for an explanation of the subtle differences between these two options.
my problem was that the data wasnt well formatted - because of my locale, I had to sed decimal point into decimal comma - that's how its written in czech republic
thanks

Why do I not see the full expected range of random numbers? [duplicate]

This question already has answers here:
Random number from a range in a Bash Script
(19 answers)
Closed 8 years ago.
I would expect the below code to generate (quasi) random numbers between 0.9 and 1.0 for RH.
randno5=$((RANDOM % 100001))
upper_limit5=$(echo "scale=10; 1*1.0"|bc)
lower_limit5=$(echo "scale=10; 1*0.9"|bc)
range5=$(echo "scale=10; $upper_limit5-$lower_limit5"|bc)
RH=`echo "scale=10; ${lower_limit5}+${range5}*${randno5}/100001" |bc`
However, when I run this code I get value between 0.9 and 0.933(3sf). Why is this the case?
$RANDOM is, at most, 32767:
RANDOM Each time this parameter is referenced, a random integer between
0 and 32767 is generated. The sequence of random numbers may be
initialized by assigning a value to RANDOM. If RANDOM is unset,
it loses its special properties, even if it is subsequently
reset.
Your modulus will have no effect as all generated numbers will be restricted to that range.

Print integer with "most appropriate" kilo/mega/etc multiplier [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to convert byte size into human readable format in java?
Given an integer, I'd like to print it in a human-readable way using kilo, mega, giga etc. multipliers. How do I pick the "best" multiplier?
Here are some examples
1 print as 1
12345 print as 12.3k
987654321 print as 988M
Ideally the number of digits printed should be configurable, e.g. in the last example, 3 digits would lead to 988M, 2 digits would lead to 1.0G, 1 digit would lead to 1G, and 4 digits would lead to 987.7M.
Example: Apple uses an algorithm of this kind, I think, when OSX tells me how many more bytes have to be copied.
This will be for Java, but I'm more interested in the algorithm than the language.
As a starting point, you could use the Math.log() function to get the "magnitude" of your value, and then use some form of associative container for the suffix (k, M, G, etc).
var magnitude = Math.log(value) / Math.log(10);
Hope this helps somehow

Resources