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