Operating System - HP-UX
1834140 Members
2519 Online
110064 Solutions
New Discussion

Re: Small Script - not working for decimals

 
Justin_132
Advisor

Small Script - not working for decimals

Hi Admins,

I hav just born new to scriptings. I tried comparing 2 digits and execute the bigger one. Hereby the script i made :

#! /sbin/sh
echo "Type any Number"
read a
echo "Type another Number"
read b
clear
echo
if [ $a -gt $b ]
then
echo Greater Number is $a
else
echo Greater Number is $b
fi

This works fine for all integers but not for decimals. Can anybody help me out.

Regds,
Just - In
11 REPLIES 11
RAC_1
Honored Contributor

Re: Small Script - not working for decimals

Shells do not do any decimal/fraction calculations. You will have to use bc/dc for that.
There is no substitute to HARDWORK
James R. Ferguson
Acclaimed Contributor

Re: Small Script - not working for decimals

Hi Justin:

The standard shells, as noted, do decimal arithmetic, so you have to resort to other means. One way is to leverage 'awk':

# echo "1.1 1.3"|awk '{if ($1 >= $2) {print $1 " geq " $2} else {print $2 " lss " $1}}'

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Small Script - not working for decimals

Hi Justin:

Sorry, I scrambled the output a bit on the last post. It is also good form to force 'awk' to convert its strings to numbers by adding '0':

# echo "1.01 1.003" | awk '{if (($1+0) >= ($2+0)) {print $1 " geq " $2} else {print $1 " lss " $2}}'

Regards!

...JRF...
Justin_132
Advisor

Re: Small Script - not working for decimals

Hi Admins,

Im really surprised what RAC said, but the below script wrks finding less/greater than 1.

#! /sbin/sh
echo "Type any Number"
read a
#echo "Type another Number"
#read b
clear
if [ $a -gt 1 ]
then
echo The Number $a is Greater than 1
else
echo The Number $a is Lesser than 1
echo
fi

Where am I missing something, or What I should I do to make this work..

Regds,
Just - In
john korterman
Honored Contributor

Re: Small Script - not working for decimals

Hi,

maybe I am missing it too, but I do not think that a comparison is an arithmetic operation....

regards,
John K.
it would be nice if you always got a second chance
Hein van den Heuvel
Honored Contributor

Re: Small Script - not working for decimals



>> I hav just born new to scriptings

Don't go there! Learn perl insteead.

>> Im really surprised what RAC said

Well, you indicated you are new to scripting. RAC (and JRF) have been around the block once or twice.
Hmmm... where would I put money.

>> but the below script wrks finding less/greater than 1.

It just 'happens' to work.
It's still wrong.

Hint: google for: +shell +unix +decimal +fractions


Kindest regards,
Hein.

(we should redefine '2 points' as: The answer was correct, but it is not what I wanted to hear. )



James R. Ferguson
Acclaimed Contributor

Re: Small Script - not working for decimals

Hi (again) Justin:

Well, compare your script (as originally written in your opening post) with the 'awk' code I offered:

# ./testsh
Type any Number
.3
Type another Number
0.1
Greater Number is 0.1

...really!?!

# echo ".3 0.1"|awk '{if (($1+0) >= ($2+0)) {print $1 " geq " $2} else {print $1 " lss " $2}}'
.3 geq 0.1
#

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Small Script - not working for decimals

Hi (again) Justin:

At the onset of this discussion I said that many shells only do decimal arithmetic. More modern versions of the Korn shell offer real number arithmetic, however. You have a Korn93 version available and this will help if you want to use it.

Change the first three lines of your original script to this:

#!/usr/dt/bin/dtksh
typeset -E a
typeset -E b

Now compare this version using ".3" and "0.1" as the input numbers.

In passing, I noted that when you used the standard Posix shell you used the statically-linked version found in '/sbin' as opposed to the dynamically linked '/usr/bin'.

For general use, '/usr/bin' is preferred since use of dynamic libraries reduces its memory footprint. For startup scripts, as root, you *must* use the '/sbin' version since '/usr' isn't mounted in the early stages of startup.

I caution you about this so you don't capriciously start using the Korn shell in '/usr/dt/bin' thinking that its an answer to all your problems!

Regards!

...JRF...
David Lodge
Trusted Contributor

Re: Small Script - not working for decimals

By default neither ksh88 or the POSIX shell support float types or variables. So if you need to use decimals you have a couple of options:
* Use dtksh, which is based on ksh93 which does support floats
* Use an external program, e.g. bc, dc or awk:
echo "4.5 + 6.7" | bc
* An old technique to keep it in shell, is to multiply all numbers by a fixed value (e.g. if you want 2 decimal places, use 100), so we have:
Fred=450
Jim=670
Shelia=$(( Fred + Jim ))
echo "$((Shelia / 100)).$((Shelia % 100))
Sandman!
Honored Contributor

Re: Small Script - not working for decimals

Hi Justin,

Not sure how your script is working since the shell will be doing a lexicographic comparison based on the ASCII character set. Fortunately the "-", 0 are numerically < than 1 while 2 thru 9 characters are numerically > than 1 in the ASCII character set, with the exception of the period. That said your script will give erroneous results for decimal digits between 1 and 2 for ex. 1.5.

hope it helps!
Arturo Galbiati
Esteemed Contributor

Re: Small Script - not working for decimals

Hi Just-in (this enjoy myself a lot!)


In UNIX shell arithmetic comparison
is limited to integer values. Here
is a tip to compare floating values
using basic shell commands.

--------- CUT HERE-----------------

#! /bin/sh
# test shell script
n1="01.401"
n2="01.350"

function compareFloatSmall
{
sort -n <<: | head -1
$n1
$n2
:
}

function compareFloatGreat
{
sort -r -n <<: | head -1
$n1
$n2
:
}

small=$(compareFloatSmall $n1 $n2)
echo "Comparing $n1 to $n2: smaller $less"
great=$(compareFloatGreat $n1 $n2)
echo "Comparing $n1 to $n2: greater $great"

--------- CUT HERE-----------------

Alternatively you can use a small 'awk' program.

--------- CUT AGAIN HERE-----------
#! /bin/sh
# A couple of examples in awk.
n1="03.550"
n2="02.550"

echo "$n1 $n2" | awk '{
if ( $1 >= $2 ) print $1
if ( $1 <= $2 ) print $2
if ( $1 > $2 ) print $1
if ( $1 < $2 ) print $2
if ( $1 == $2 ) print $1, $2
}'
--------- CUT AGAIN HERE-----------

HTH,
Art