Comparing float values in bash

8,443

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 saved 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 -expression 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
Share:
8,443

Related videos on Youtube

Gilles 'SO- stop being evil'
Author by

Gilles 'SO- stop being evil'

Updated on September 18, 2022

Comments

  • Gilles 'SO- stop being evil'
    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
      jimmij over 9 years
      bash can handle only integers.
  • YoloTats.com
    YoloTats.com over 9 years
    You can use: if [ $(echo "$ROTATION == 90" | bc) -eq 1 ]
  • Atul Vekariya
    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
    Angel Todorov over 9 years
    Since this is bash: if (( $(bc <<< "$ROTATION == 90") == 1 ))
  • Atul Vekariya
    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
    Costas over 9 years
    You have to more think above. 90,001 == 90 in your script.
  • Atul Vekariya
    Atul Vekariya over 9 years
    In bash you can't do directly math operations with floating point. So you should use bc, awk, perl, etc.
  • mikeserv
    mikeserv over 9 years
    @Costas - good point. Will fix.
  • Costas
    Costas over 9 years
    In your last comparation 90.00 != 90.000
  • Stéphane Chazelas
    Stéphane Chazelas over 9 years
    @Costas, no, but that 90.00 fails the if the value is always expressed as 90.000 assumption.