Re: Binary math operations (and, or, etc.)
Re: Binary math operations (and, or, etc.)
- Subject: Re: Binary math operations (and, or, etc.)
- From: has <email@hidden>
- Date: Thu, 9 Jun 2005 10:55:09 +0100
I wrote:
>AppleScript doesn't provide built-in bitwise operators, so you'll need to provide your own. Also, be aware that AppleScript AS integers are only 30 bits long
Actually, it occurs to me that AppleScript's real type has better precision than its integer type, so it would be possible to support up to around 52-bits. Also, scratch that last code as it had a subtle but significant bug in it; what happens when one's math's too shot for a formal proof and one's unittests don't cover certain cases <sigh>. (This is why I prefer languages that provide all this crap as standard.:p) Anyway, the following code should address both issues (it passes the new tests and has been sanity-checked against Python's bitwise operators at any rate):
-- PRIVATE
(* Notes:
- AS integers are only 29+1 bits in size so non-fractional reals from -(2^52) to 2^52-1 are also permitted, allowing bitwise operations on up to 52+1 bits
- integer and real precisions are highly unlikely ever to change in AS 1.x so these numbers are hardwired for simplicity
*)
property _maxIntegerPrecision : 29
property _maxRealPrecision : 52
property _minInteger : -(2 ^ _maxIntegerPrecision) as integer
property _maxInteger : (2 ^ _maxIntegerPrecision) - 1 as integer
property _minReal : -(2 ^ _maxRealPrecision)
property _maxReal : (2 ^ _maxRealPrecision) - 1
on _asNum(n)
considering punctuation, hyphens and white space
set n to n as number
end considering
if n < _minReal or n > _maxReal then
error (n as string) & " exceeds " & _maxRealPrecision & "-bit precision limit." number -1704
else if n mod 1 is not 0 then
error (n as string) & " isn't a whole number." number -1704
end if
return n
end _asNum
on _flipOperand(n)
if n < 0 then
return {-n - 1, 1}
else
return {n, 0}
end if
end _flipOperand
on _operator(a, b, obj, opName)
try
set a to _asNum(a)
set b to _asNum(b)
set rm to obj's op(a < 0, b < 0)
set {a, am} to _flipOperand (a)
set {b, bm} to _flipOperand (b)
set res to 0
set e to 0
repeat until a is 0 and b is 0
if obj's op(((a + am) mod 2) is not 0, ((b + bm) mod 2) is not 0) then
set res to res + 2 ^ e
end if
set a to a div 2
set b to b div 2
set e to e + 1
end repeat
--log res
if rm then set res to res - (2 ^ e)
if res < _minInteger or res > _maxInteger then
return res
else
return res as integer
end if
on error eMsg number eNum
error "Can't " & opName & ": " & eMsg number eNum
end try
end _operator
-- PUBLIC
on bNOT(n)
try
set n to -(_asNum(n)) - 1
if n < _minInteger or n > _maxInteger then
return n
else
return n as integer
end if
on error eMsg number eNum
error "Can't bNOT: " & eMsg number eNum
end try
end bNOT
on bAND(a, b)
script obj
on op(a, b)
return a and b
end op
end script
return _operator(a, b, obj, "bAND")
end bAND
on bOR(a, b)
script obj
on op(a, b)
return a or b
end op
end script
return _operator(a, b, obj, "bOR")
end bOR
on bXOR(a, b)
script obj
on op(a, b)
return (a or b) and not (a and b)
end op
end script
return _operator(a, b, obj, "bXOR")
end bXOR
HTH
has
--
http://freespace.virgin.net/hamish.sanderson/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden