Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Sep 2004 15:48:09 -0500
From:      Dan Nelson <dnelson@allantgroup.com>
To:        Andrew <infofarmer@mail.ru>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: 64-bit arithmetic in scripts?
Message-ID:  <20040930204808.GE22530@dan.emsphone.com>
In-Reply-To: <004901c4a729$61fc7810$4611a8c0@SATPC>
References:  <000601c4a720$99264270$4611a8c0@SATPC> <20040930194001.GD22530@dan.emsphone.com> <004901c4a729$61fc7810$4611a8c0@SATPC>

next in thread | previous in thread | raw e-mail | index | archive | help
In the last episode (Oct 01), Andrew said:
> Thanks! I haven't thought about using expr.
> 
> How come that my expr(1) manpage has nothing to say about -e option?
> In fact my expr(1) does not accept it. I have FreeBSD 4.10. I've just
> looked into a current manpage from www.freebsd.org, and it says
> something about 4.x compatibility.
> 
> What is the best way to go if I need to write scripts now, but I'm
> planning to switch to 5.x later? Can I upgrade expr(1) now? If not,
> what should I do?

In 4.x, expr does 64-bit math by default.   Apparently POSIX requires
that expr use whatever the systems' "signed long" size is, so the
default was changed for 5.x, and -e was added to get the old behaviour.

If you want your script to work on both, you'll have to do a feature
test.  I started out just testing expr and expr -e, but it sort of
grew...  The following script will check the shell's math, two ways of
calling expr, and finally fall back on calling bc.  As long as you just
use the basic math operators, quote your "*"'s, and put spaces between
everything, all the methods should be compatible, and your script will
work on any bourne-compatible shell :)

#! /bin/sh

if [ x$(( 65536 * 65536 )) = "x4294967296" ] ; then
  shellarith() { echo $(( $@ )) ; }
  MATH="shellarith"
else
  if [ x`expr 65536 "*" 65536` = "x4294967296" ] ; then
    MATH="expr"
  else
    if [ x`expr -e 65536 "*" 65536 2>/dev/null` = x"4294967296" ] ; then
      MATH="expr -e"
    else
      if [ x`echo 65536 "*" 65536 | bc` = "x4294967296" ] ; then
        bcfunc() { echo "$@" | bc ; }
        MATH="bcfunc"
      else
        echo "Can't do 64-bit math noway nohow"
      fi
    fi
  fi
fi

echo "Using $MATH"
bigval=`$MATH 65536 "*" 65536`
echo $bigval

-- 
	Dan Nelson
	dnelson@allantgroup.com



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040930204808.GE22530>