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