1. bitwise operations limited to 32 bits
- Posted by petelomax May 03, 2010
- 1410 views
Someone has ripped out the above error, but I fear they have been a little over-zealous. I fully agree that and_bits() with either parameter 32 bits or less needed to be changed, but the same is not true for or_bits, xor_bits, and not_bits.
constant nines = #999999999, -- more than 32 bits f32 = #FFFFFFFF, m1 = -1 printf(1,"%08x\n",and_bits(nines,f32)) -- OK printf(1,"%08x\n",and_bits(nines,m1)) -- OK printf(1,"%08x\n",and_bits(nines,nines)) -- should crash printf(1,"%08x\n",or_bits(nines,f32)) -- should crash printf(1,"%08x\n",or_bits(nines,m1)) -- should crash printf(1,"%08x\n",or_bits(nines,nines)) -- should crash printf(1,"%08x\n",xor_bits(nines,f32)) -- should crash printf(1,"%08x\n",xor_bits(nines,m1)) -- should crash printf(1,"%08x\n",xor_bits(nines,nines)) -- should crash printf(1,"%08x\n",not_bits(f32)) -- OK printf(1,"%08x\n",not_bits(m1)) -- OK printf(1,"%08x\n",not_bits(nines)) -- should crash
2. Re: bitwise operations limited to 32 bits
- Posted by DerekParnell (admin) May 03, 2010
- 1408 views
... but the same is not true for or_bits, xor_bits, and not_bits.
Why?
3. Re: bitwise operations limited to 32 bits
- Posted by petelomax May 03, 2010
- 1404 views
... but the same is not true for or_bits, xor_bits, and not_bits.
Why?
Because code such as
function setBit(atom mask, integer bit) return or_bits(mask,power(2,bit-1)) end function atom mask mask = setBit(0,35)
will now fail silently, leaving mask 0.
Of course the literal 35 makes this a bit blatent, but what if it is an enum, so your code works fine until you insert a few more flags?
As I said, there is a strong case for and_bits(<anything>,#FFFFFFFF) to return the perfectly valid answer, but are there any real-world or_bits etc examples that I am missing whereby it should quietly and incorrectly set the top bits of the input to 0s?
Regards, Pete
4. Re: bitwise operations limited to 32 bits
- Posted by DerekParnell (admin) May 04, 2010
- 1367 views
... but the same is not true for or_bits, xor_bits, and not_bits.
Why?
Because code such as
function setBit(atom mask, integer bit) return or_bits(mask,power(2,bit-1)) end function atom mask mask = setBit(0,35)
will now fail silently, leaving mask 0.
Of course the literal 35 makes this a bit blatent, but what if it is an enum, so your code works fine until you insert a few more flags?
As I said, there is a strong case for and_bits(<anything>,#FFFFFFFF) to return the perfectly valid answer, but are there any real-world or_bits etc examples that I am missing whereby it should quietly and incorrectly set the top bits of the input to 0s?
As documented, these bitwise functions only deal with sets of 32-bits, so therefore there are no 'top' bits outside those 32 bits. Also as documented, these functions only work on the lower 32-bits of any value presented to them; other bits are ignored. This is a very useful property when bit-twiddling for hashing and encryption. If one is play with bits for other purposes, those algorithms using the bitwise functions must also be intimately aware of what is happening to values under their care. So I would maintain that the example function you present ought to be rewritten more like ...
function setBit(atom mask, integer bit) if bit < 1 or bit > 32 then crash("'bit' parameter value %d is out of range", bit) end if return or_bits(mask,power(2,bit-1)) end function atom mask mask = setBit(0,35)
results in a crash and the message
'bit' parameter value 35 is out of range
The coder must take some responsibility at some point. The language cannot be expected to be the nanny.
Another approach might be to have a with option that suppresses certain runtime checks such as large values in bitwise functions. For example ...
without bit_errors -- No crashes with large values. --with bit_errors -- Crashes with large values (the default). function setBit(atom mask, integer bit) return or_bits(mask,power(2,bit-1)) end function atom mask mask = setBit(0,35)
5. Re: bitwise operations limited to 32 bits
- Posted by petelomax May 04, 2010
- 1394 views
As documented, these bitwise functions only deal with sets of 32-bits, so therefore there are no 'top' bits outside those 32 bits. Also as documented, these functions only work on the lower 32-bits of any value presented to them; other bits are ignored.
So http://oe.cowgar.com/docs/eu400_0057.html#_1511_bitwiseoperations is out of date?
Another approach might be to have a with option that suppresses certain runtime checks such as large values in bitwise functions.
Not on my account. As I see it, what I said was either right or wrong, not somewhere inbetween. Your call, I'm not really bothered. And no, I'm not offended or sulking, it is genuinuely no skin off my nose either way.
Regards,
Pete
6. Re: bitwise operations limited to 32 bits
- Posted by SPringle May 04, 2010
- 1335 views
So I would maintain that the example function you present ought to be rewritten more like ...
function setBit(atom mask, integer bit) if bit < 1 or bit > 32 then crash("'bit' parameter value %d is out of range", bit) end if return or_bits(mask,power(2,bit-1)) end function atom mask mask = setBit(0,35)
results in a crash and the message
'bit' parameter value 35 is out of range
The coder must take some responsibility at some point. The language cannot be expected to be the nanny.
Why not use the type checking facility:
type register_bit(integer i) return i > 0 or i < 33 end type function setBit(atom mask, register_bit bit) return or_bits(mask,power(2,bit-1)) end function
I think this feature is quite under-appreciated.
Shawn Pringle
7. Re: bitwise operations limited to 32 bits
- Posted by DerekParnell (admin) May 05, 2010
- 1302 views
Why not use the type checking facility:
type register_bit(integer i) return i > 0 or i < 33 end type function setBit(atom mask, register_bit bit) return or_bits(mask,power(2,bit-1)) end function
I think this feature is quite under-appreciated.
I was going to use that but it complicated the message I was trying to get across, also a problem with the current type system is that without type_check can be used to get around it.
8. Re: bitwise operations limited to 32 bits
- Posted by SPringle May 05, 2010
- 1267 views
I don't think it is bad that you can turn type-checking off. If you think it should stay on leave it on. In the case of hard coding the condition you can't turn it off, even when you know the code is error free.
In my opinion, the problem is when you type check a long sequence of values testing each member against a test and if the sequence is very long, it is really hard to understand what part of the list is wrong.
type datetime_list(object s) if atom(s) then return 0 end if for i = 1 to length(s) do if not datetime(s[i]) then return 0 end if end for return 1 end type datetime_list list list = get_list() -- type check error here of list
This routine will say that the list is wrong in the routine that uses the type and put an impossibly long list into ex.err. The first ten records will look fine. On the other hand, it seems reasonable to do the following:
type datetime_list(sequence s) datetime dt for i = 1 to length(s) do dt = s[i] -- type check error here end for return 1 end type datetime_list list list = get_list() -- type check error here of list
If the value s[142] is not a valid datetime, this type routine implementation would make it clear where the problem is via the variable i. However, when you call the type as function to validate data you will get a crash in the validation process. We do not want that.
sequence s = get_list() if datetime_list(s) then -- type check error here! BAD
The first implementation is the correct one, but the second is much simpler and will be better optimized. It would be nice if the interpreter would act differently when you call the type as a function. As a function, a type-check failure inside the type-check could just exit the call chain with a return value of 0, ala longjmp for example.
Shawn Pringle
9. Re: bitwise operations limited to 32 bits
- Posted by SPringle May 05, 2010
- 1270 views
If you don't like the way the bit op operations work. You are not alone. You can always override them. The easiest way is to pass atoms to int_to_bits do the op and convert them back:
override function or_bits(atom a, atom b) return bits_to_int(eu:or_bits(int_to_bits(a),int_to_bits(b))) end function
This will give you the functionality you desire and you can optimize it later on. You might want to make different types to replace 'atom' here for catching numbers that are too big or have a fractional part.
Shawn Pringle
10. Re: bitwise operations limited to 32 bits
- Posted by SPringle May 05, 2010
- 1291 views
Oops, those int_to_bits function calls should take a bit_count parameter of 52.
override function or_bits(atom a, atom b) return bits_to_int(or_bits(int_to_bits(a,52), int_to_bits(b,52))) end function