Unix Shell - Possible to compare real numbers?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > October 2006 > Possible to compare real numbers?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Possible to compare real numbers?
osiris@abydos.kmt

2006-10-26, 7:16 am

Is there a way to do this?

VAR=2.1
if [ "$VAR" -gt 1.333 ] ; then
do something
fi

I get:
-bash: [: 2.1: integer expression expected

Do I have to multiply both real numbers by e.g. 1000
in order to compare integers?

Thanks for any help.
Michal Nazarewicz

2006-10-26, 7:16 am

osiris@abydos.kmt writes:

> Is there a way to do this?
>
> VAR=2.1
> if [ "$VAR" -gt 1.333 ] ; then
> do something
> fi
>
> I get:
> -bash: [: 2.1: integer expression expected
>
> Do I have to multiply both real numbers by e.g. 1000
> in order to compare integers?


Shell does not support floating numbers. You'll have to use fixed
point numbers saved as integers[1] (eg. 1.333 is 1333, 2.1 is 2100)
but beware that you are limited by the maximum value integer type can
hold in shell[2].

You can also use another language instead of shell.

You can also try using bc for floating point numbers calculations.


[1] I've even wrote two functions itf and fti to help operate on such
numbers:

#v+
# usage: fti <float> [<number of digits after point>]
fti () {
# Check args
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
echo fti: invalid number of arguments >&2
return 1
fi

# Trim
set -- $1 "${2-2}"
if [ $# -ne 2 ]; then
echo fti: real number expected >&2
return 1
fi

# Check if real number and split
case $1 in (-*) set -- - "${1#-}" "$2";; (+*|*) set -- '' "$@" ;; esac
case $2 in
(*.|*.*.*|*[^0-9.]*) echo fti: real number expected >&2; return 1 ;;
(*.*) set -- "$1" "${2%.*}" "$3" "${2#*.}" ;;
(*[^0]*) set -- "$@" '' ;;
(*) echo 0; return 0 ;;
esac

# Set corect number of digits
while [ $3 -lt 0 ]; do set -- "${2%?}" $(( $3 + 1 )); done
while [ ${#4} -gt $3 ]; do set -- "$1" "$2" "$3" "${4%?}"; done
while [ ${#4} -lt $3 ]; do set -- "$1" "$2" "$3" "${4}0" ; done

# Return
set -- "$1" "$2$4"
while [ X"$2" != X"${2#0}" ]; do set -- "$1" "${2#0}"; done
if [ -n "$2" ]; then echo "$1$2"; else echo 0; fi
}

# usage: itf <int> [<number of digits after point>]
itf () {
# Check args
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
echo itf: invalid number of arguments >&2
return 1
fi

# Trim
set -- $1 "${2-2}"
if [ $# -ne 2 ]; then
echo itf: integer expected >&2
return 1
fi

# It's not an integer; or zero
case $1 in (-*) set -- - "${1#-}" "$2";; (+*|*) set -- '' "$@" ;; esac
case $2 in
(*[^0-9]*) echo itf: integer expected >&2; return 1 ;;
(*[^0]*) ;;
(*) echo 0; return 0 ;;
esac

# Negative number of digits
if [ $3 -lt 0 ]; then
while [ $3 -lt 0 ]; do set -- "$1" "${2}0" $(( $3 + 1 )); done
echo "$1$2"
return 0
fi

# Split
while [ ${#2} -lt $3 ]; do set -- "$1" "0$2" "$3"; done
while [ ${#4} -lt $3 ]; do
set -- "$1" "$2" "$3" "$4" "${2%?}"
set -- "$1" "$5" "$3" "${2#$5}$4"
done

# Return
case $4 in
(*[^0]*) echo "$1${2:-0}.$4" ;;
(*) echo "$1$2" ;;
esac
}
#v-

[2] I've also written functions to operate on big ints in shell but
it's a bit long so I won't include it here.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com