[Gllug] Unsigned shell arithmetic
Nix
nix at esperi.demon.co.uk
Wed Dec 5 08:34:15 UTC 2001
On Tue, 04 Dec 2001, tet at accucard.com uttered the following:
> Anyone know how I can force unsigned arithmetic in a shell?
You can't. The Single Unix Spec is not very clear on this :(
`Only integer arithmetic is required.' --- and no provision is made for
*unsigned* integer arithmetic.
> echo $((65536 * 65000))
Of course because there are no guaranteed bounds this might overflow
even if you added two and two ;)
> returns -35127296 both bash and pdksh, although genuine ksh on Solaris
> returns 4259840000, which in this instance is what I want (fortunate,
Undefined behaviour syndrome :(
> as the script is primarily going to be used on Solaris). pdksh has a
> -U option to typeset, which implies it'll do this, but it doesn't seem
> to work.
... and isn't portable :(
> But I was more interested in whether or not it could be done
> in Bourne shell, rather than bash, pdksh, zsh or any of the other
> "enhanced" shells.
Not a chance. The Bourne shell isn't a POSIX shell and hence doesn't
have shell arithmetic at all. You'd have more luck in a POSIX shell, but
it doesn't seem that they have allowed for this either.
> Also, does anyone know of a way to do bitwise operations in a standard
> Bourne shell?
There is none, as there is no shell arithmetic. For POSIX shells, SuSv2
states
,----
| The arithmetic expression will be processed according to the rules of
| the ISO C standard, with the following exceptions:
|
| * Only integer arithmetic is required.
|
| * The sizeof() operator and the prefix and postfix ++ and --
| operators are not required.
`----
I don't think bitwise manipulation is classifiable as `integer
arithmetic', somehow.
> I can do it in ksh or bash with $((a & b)), but at least
Non-portable (assuming my reading of the spec to be correct; I'm not
confident of that).
> on Solaris, standard Bourne shell doesn't support that construct, and
> neither does expr.
Stick a #!/bin/ksh at the top of the script, and get the script to
reinvoke itself with ksh if some idiot starts it with `sh', viz
if [ "$(echo foo)" != "`echo foo`" ]; then
exec $0 "$@"
echo 'Error: needed shell (/bin/ksh) not found.' >&2
exit 1
fi
(do that as close to the top of the script as you can, of course.)
> PS. Yes, I know I can do arbitrary precision unsigned arithmetic in dc,
> but dc doesn't have a bitwise AND operator, which unfortunately I need.
You'll have to either write C or implement bitwise arithmetic in dc or
sed in terms of decimal manipulations. This is definitely possible ---
see the seders mailing list archives for an implementation by (who else)
Greg Ubben --- but it's, er, hardly readable.
> PPS. No comments about how I should be using perl, python or any other
`You should be using Emacs Lisp.'
*stirs mud vigorously*
> It's not an option for this particular task.
> The client has specified an unmolested Solaris 7 box, with no
> additional software installed.
I think you'll need /bin/ksh, but that's always there, isn't it?
--
`The situation is completely under control. All of them were killed.'
--- Alim Razim, for the Northern Alliance, demonstrating fine
command of traditional Afghan prisoner control techniques.
--
Gllug mailing list - Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug
More information about the GLLUG
mailing list