1. bitwise operations limited to 32 bits

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 
new topic     » topic index » view message » categorize

2. Re: bitwise operations limited to 32 bits

petelomax said...

... but the same is not true for or_bits, xor_bits, and not_bits.

Why?

new topic     » goto parent     » topic index » view message » categorize

3. Re: bitwise operations limited to 32 bits

DerekParnell said...
petelomax said...

... 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

new topic     » goto parent     » topic index » view message » categorize

4. Re: bitwise operations limited to 32 bits

petelomax said...
DerekParnell said...
petelomax said...

... 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) 
new topic     » goto parent     » topic index » view message » categorize

5. Re: bitwise operations limited to 32 bits

DerekParnell said...

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?

DerekParnell said...

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

new topic     » goto parent     » topic index » view message » categorize

6. Re: bitwise operations limited to 32 bits

DerekParnell said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: bitwise operations limited to 32 bits

SPringle said...

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.

new topic     » goto parent     » topic index » view message » categorize

8. Re: bitwise operations limited to 32 bits

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

new topic     » goto parent     » topic index » view message » categorize

9. Re: bitwise operations limited to 32 bits

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

new topic     » goto parent     » topic index » view message » categorize

10. Re: bitwise operations limited to 32 bits

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 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu