Comparing float values in bash
Solution 1
You can use bc command for this puspose:
echo "$ROTATION == 90"|bc
and you will get 0 in case of false and 1 in case of true
P.S. Be aware that comparing for equivalence floating point numbers is not the wisest thing in programming :)
Solution 2
Because they are strings, you can compare multiple concatenated strings against one another. Balancing values makes for simple means of handling multiple shell tests at once.
[ "${num#90.}${num%[!0]*}" = "90${num%[!0]*}" ] && do_it
But that only works if $num
is definitely a number. You can validate an integer value for $num
like:
[ "$num" -eq "$num" ]
Or a float like:
[ "${#num}${num#*.}" -ne "${num%.*}${#num}" ]
But case
is usually best...
case ".${num##*[!-.0-9]*}" in
(.|.[!9]*|.9[!0]*|.90.*[!0]*)
! :;;esac
Where outside utilities are concerned, I usually prefer dc
to bc
because it can be used to execute arbitrary system commands:
dc -e '[!echo execute arbitrary system command]s=' \
-e '90 90.0 =='
Everything within the []
brackets is a string that is s
aved to the array named =
and which is executed as a dc
command if the top two values on the main stack (here 90 and 90.0) =
one another. The first !
operator within the string is !
operator which executes as a system command all that follows it. You can also read from input for more dc
script to execute conditionally with the ?
operator.
The -e
xpression syntax is a GNUism, though. You can get the same effect portably with a heredoc or echoing the commands over a pipe to its stdin.
For example:
! dc -e '[!kill -PIPE "$PPID"]s= 90 90.0 ==' && do_it
Related videos on Youtube
Gilles 'SO- stop being evil'
Updated on September 18, 2022Comments
-
Gilles 'SO- stop being evil' over 1 year
My if expression always evaluates to TRUE somehow. ROTATION variable is 0.000 or 90.000, a float value or it seems so
ROTATION="$(mediainfo --Inform="Video;%Rotation%" $VIDEO$ORIGINALEXTENTION)" echo $ROTATION ROTATION_PARAMETER="" if [ $ROTATION -eq 90 ] then ROTATION_PARAMETER=" --rotate=4" fi echo $ROTATION_PARAMETER
How can I compare a variable to a value?
-
jimmij over 9 years
bash
can handle only integers.
-
-
YoloTats.com over 9 yearsYou can use:
if [ $(echo "$ROTATION == 90" | bc) -eq 1 ]
-
Atul Vekariya over 9 years@jofel, the good practice is to make it on this way: if [ "$(echo "$ROTATION == 90" | bc)" -eq 1 ] :)
-
Angel Todorov over 9 yearsSince this is bash:
if (( $(bc <<< "$ROTATION == 90") == 1 ))
-
Atul Vekariya over 9 years@glennjackman, thank you for the idea. I personally prefer to use old sh syntax :) But you should use -eq 1 because == in bash is to compare strings
-
Costas over 9 yearsYou have to more think above. 90,001 == 90 in your script.
-
Atul Vekariya over 9 yearsIn bash you can't do directly math operations with floating point. So you should use bc, awk, perl, etc.
-
mikeserv over 9 years@Costas - good point. Will fix.
-
Costas over 9 yearsIn your last comparation
90.00
!=90.000
-
Stéphane Chazelas over 9 years@Costas, no, but that 90.00 fails the if the value is always expressed as 90.000 assumption.