From: Iban
Subject: math operation and bits operations
Date: 
Message-ID: <3BAA665A.5A1CBB8B@yahoo.fr>
Greetings,

I want your advise for a little function that I need.
I have to "reconstruct" a bit mask according to the following rules (its
probably very standard) :
    is given : - the number of bits in masks is 10
	       - a bit mask of member to change.
               - a bit mask of new value
               - the original bit mask

example :
    000100110 original bit mask
    100110011 bit mask of member to change
    101110111 bit mask of new value
    --------
    100110111 bit mask result

I know that there is a curious bit (number 6) in new value but it
doesn't matter (it is for the example).

Here is my solution. I'm not totally satisfy of it. But I have some
logical problems with this function. Is there any way to do that with a
complicated but more "logical", combination of and, or, nand, xor, ....
? And would it be more efficient ?

(defun compute-mask (mask mask-of-member-to-change new-value)
  (loop with result-mask = 0
        for i from 0 to 9 ;; my mask length is fix
        if (logbitp i mask-of-member-to-change)
        do (when (logbitp i new-value) (incf result-mask (ash 1 i)))
        else do (when (logbitp i mask) (incf result-mask (ash 1 i)))
        finally (return result-mask)))

Thanks.

From: Tim Moore
Subject: Re: math operation and bits operations
Date: 
Message-ID: <9odubd$1cc$0@216.39.145.192>
Check out the logical operators logand, logior, etc.  Here's one solution
to your problem using those functions:

(defun compute-mask (mask mask-of-member-to-change new-value)
  (logior (logandc2 mask mask-of-member-to-change)
          (logand new-value mask-of-member-to-change)))

If the constraint on a 10bit long mask is actually important to you, you
can use ldb to mask off the result (or the inputs):

(ldb (byte 10 0) result)

Tim

On Thu, 20 Sep 2001, Iban wrote:

> Greetings,
> 
> I want your advise for a little function that I need.
> I have to "reconstruct" a bit mask according to the following rules (its
> probably very standard) :
>     is given : - the number of bits in masks is 10
> 	       - a bit mask of member to change.
>                - a bit mask of new value
>                - the original bit mask
> 
> example :
>     000100110 original bit mask
>     100110011 bit mask of member to change
>     101110111 bit mask of new value
>     --------
>     100110111 bit mask result
> 
> I know that there is a curious bit (number 6) in new value but it
> doesn't matter (it is for the example).
> 
> Here is my solution. I'm not totally satisfy of it. But I have some
> logical problems with this function. Is there any way to do that with a
> complicated but more "logical", combination of and, or, nand, xor, ....
> ? And would it be more efficient ?
> 
> (defun compute-mask (mask mask-of-member-to-change new-value)
>   (loop with result-mask = 0
>         for i from 0 to 9 ;; my mask length is fix
>         if (logbitp i mask-of-member-to-change)
>         do (when (logbitp i new-value) (incf result-mask (ash 1 i)))
>         else do (when (logbitp i mask) (incf result-mask (ash 1 i)))
>         finally (return result-mask)))
> 
> Thanks.
> 
> 
From: Barry Margolin
Subject: Re: math operation and bits operations
Date: 
Message-ID: <Qivq7.29$ur3.2070@burlma1-snr2>
In article <············@216.39.145.192>,
Tim Moore  <·····@herschel.bricoworks.com> wrote:
>Check out the logical operators logand, logior, etc.  Here's one solution
>to your problem using those functions:
>
>(defun compute-mask (mask mask-of-member-to-change new-value)
>  (logior (logandc2 mask mask-of-member-to-change)
>          (logand new-value mask-of-member-to-change)))

Can't you do it without the logandc2?  My version is:

(defun compute-mask (orig-mask members-to-change new-value)
  (logior orig-mask
          (logand new-value members-to-change)))

>On Thu, 20 Sep 2001, Iban wrote:
>
>> Greetings,
>> 
>> I want your advise for a little function that I need.
>> I have to "reconstruct" a bit mask according to the following rules (its
>> probably very standard) :
>>     is given : - the number of bits in masks is 10
>> 	       - a bit mask of member to change.
>>                - a bit mask of new value
>>                - the original bit mask
>> 
>> example :
>>     000100110 original bit mask
>>     100110011 bit mask of member to change
>>     101110111 bit mask of new value
>>     --------
>>     100110111 bit mask result

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Tim Moore
Subject: Re: math operation and bits operations
Date: 
Message-ID: <9oe1of$h4m$0@216.39.145.192>
On Thu, 20 Sep 2001, Barry Margolin wrote:

> In article <············@216.39.145.192>,
> Tim Moore  <·····@herschel.bricoworks.com> wrote:
> >Check out the logical operators logand, logior, etc.  Here's one solution
> >to your problem using those functions:
> >
> >(defun compute-mask (mask mask-of-member-to-change new-value)
> >  (logior (logandc2 mask mask-of-member-to-change)
> >          (logand new-value mask-of-member-to-change)))
> 
> Can't you do it without the logandc2?  My version is:
> 
> (defun compute-mask (orig-mask members-to-change new-value)
>   (logior orig-mask
>           (logand new-value members-to-change)))

My understanding of the problem, although it's not clear from the example,
is that 0s in the new-value appear in the result if the appropriate bit in
mask-of-member-to-change is set.

Tim

 > 
> >On Thu, 20 Sep 2001, Iban wrote:
> >
> >> Greetings,
> >> 
> >> I want your advise for a little function that I need.
> >> I have to "reconstruct" a bit mask according to the following rules (its
> >> probably very standard) :
> >>     is given : - the number of bits in masks is 10
> >> 	       - a bit mask of member to change.
> >>                - a bit mask of new value
> >>                - the original bit mask
> >> 
> >> example :
> >>     000100110 original bit mask
> >>     100110011 bit mask of member to change
> >>     101110111 bit mask of new value
> >>     --------
> >>     100110111 bit mask result
From: Kent M Pitman
Subject: Re: math operation and bits operations
Date: 
Message-ID: <sfw8zf9me1i.fsf@world.std.com>
Tim Moore <·····@herschel.bricoworks.com> writes:

> On Thu, 20 Sep 2001, Barry Margolin wrote:
> 
> > In article <············@216.39.145.192>,
> > Tim Moore  <·····@herschel.bricoworks.com> wrote:
> > >Check out the logical operators logand, logior, etc.  Here's one solution
> > >to your problem using those functions:
> > >
> > >(defun compute-mask (mask mask-of-member-to-change new-value)
> > >  (logior (logandc2 mask mask-of-member-to-change)
> > >          (logand new-value mask-of-member-to-change)))
> > 
> > Can't you do it without the logandc2?  My version is:
> > 
> > (defun compute-mask (orig-mask members-to-change new-value)
> >   (logior orig-mask
> >           (logand new-value members-to-change)))
> 
> My understanding of the problem, although it's not clear from the example,
> is that 0s in the new-value appear in the result if the appropriate bit in
> mask-of-member-to-change is set.

Yes, the problem description is weak there, and the example gives no extra
clue.

The problem description is also weak in that it says it's a mask of bits
to change, yet when the bit is 1 in the input, it appears not to change.
I would have expected an xor affect from the problem description, but the
example suggests not.

It's curious how many ways such a simple problem can be flawed in its
description.

> > >On Thu, 20 Sep 2001, Iban wrote:
> > >
> > >> Greetings,
> > >> 
> > >> I want your advise for a little function that I need.
> > >> I have to "reconstruct" a bit mask according to the following rules (its
> > >> probably very standard) :
> > >>     is given : - the number of bits in masks is 10
> > >> 	       - a bit mask of member to change.
> > >>                - a bit mask of new value
> > >>                - the original bit mask
> > >> 
> > >> example :
> > >>     000100110 original bit mask
> > >>     100110011 bit mask of member to change
> > >>     101110111 bit mask of new value
> > >>     --------
> > >>     100110111 bit mask result
> 
From: Iban
Subject: Re: math operation and bits operations
Date: 
Message-ID: <3BAB895D.C7D40CD@yahoo.fr>
Kent M Pitman a �crit :

> Yes, the problem description is weak there, and the example gives no extra
> clue.
>
> The problem description is also weak in that it says it's a mask of bits
> to change, yet when the bit is 1 in the input, it appears not to change.
> I would have expected an xor affect from the problem description, but the
> example suggests not.
>
> It's curious how many ways such a simple problem can be flawed in its
> description.

Sorry about that, I should have explain it in the way Kaz Kylheku understoud it :


I want it work like this: whenever there is a 1
bit in the ``member to change'' mask, the corresponding bit
from ``new value'' should be  used in the resulting value.
Wherever there is a zero, the bit should be taken from the
original bitmask.

Then his solution is what my job's friend remind me : "Use the a Karnaugh map to
describe your problem"

So, as some of you said I suspect the solution is :

  (defun compute-mask (original change new)
    (logior (logandc1 change original)
            (logand change new)))

thanks a lot.
From: Kalle Olavi Niemitalo
Subject: Re: math operation and bits operations
Date: 
Message-ID: <87bsk5tqfi.fsf@Astalo.y2000.kon.iki.fi>
Iban <········@yahoo.fr> writes:

> example :
>     000100110 original bit mask
>     100110011 bit mask of member to change
>     101110111 bit mask of new value
>     --------
>     100110111 bit mask result

So basically, each bit of "bit mask of member to change" selects
whether to take that bit from "original bit mask" or from "bit
mask of new value".

  (defun compute-mask (original change new)
    (logior (logandc1 change original)
            (logand change new)))

  (format nil "~B" (compute-mask #B000100110
                                 #B100110011
                                 #B101110111))
  => "100110111"

> Is there any way to do that with a complicated but more
> "logical", combination of and, or, nand, xor, .... ?  And would
> it be more efficient ?

The function I wrote above uses basically the same algorithm as
yours; it just computes all the bits in the same Lisp operation.
I guess this will be faster on most hardware.  Try it.
From: Kaz Kylheku
Subject: Re: math operation and bits operations
Date: 
Message-ID: <kvAq7.31560$jY.799978@news1.rdc1.bc.home.com>
In article <·················@yahoo.fr>, Iban wrote:
>Greetings,
>
>I want your advise for a little function that I need.
>I have to "reconstruct" a bit mask according to the following rules (its
>probably very standard) :
>    is given : - the number of bits in masks is 10
>	       - a bit mask of member to change.
>               - a bit mask of new value
>               - the original bit mask
>
>example :
>    000100110 original bit mask
>    100110011 bit mask of member to change
>    101110111 bit mask of new value
>    --------
>    100110111 bit mask result

In this example, the third operand is superfluous, because the
result is simply the OR of the first two operands. So the example
isn't general enough to illustrate the full scope of the operation.

Presumably, you want it work like this: whenever there is a 1
bit in the ``member to change'' mask, the corresponding bit
from ``new value'' should be  used in the resulting value.
Wherever there is a zero, the bit should be taken from the
original bitmask.

>I know that there is a curious bit (number 6) in new value but it
>doesn't matter (it is for the example).
>
>Here is my solution. I'm not totally satisfy of it. But I have some
>logical problems with this function. Is there any way to do that with a
>complicated but more "logical", combination of and, or, nand, xor, ....
>? And would it be more efficient ?

Of course there is. Write a truth table out and then find the boolean
function which does the job. Use a Karnaugh map or other means
for reduction.

Or, you can take this logical approach: the role of the second operand
is clearly to select whether the first or third operand's value is taken.
Let's call them X, Y and Z. Y serves as a discriminator, or selector
between X and Z.

If Y is 1, then we take the value of Z. Otherwise, we take X.

We can write this logic as a conjunction of two conditionals:

	(Y -> Z) ^ (~Y -> X)	``If Y, then Z and if not Y then X''.

The conditionals can be replaced by OR expressions by the
standard equivalence ``If P, then Q''  <==>  ``(not P) or Q'':

	(~Y v Z) ^ (Y v X)

Now to apply this to entire bitfields in parallel, the logical and and
or become bitwise and and or, and not becomes a bitwise complement.

Example:


X        000100110    original bit mask
Y        100110011    bit mask of member to change
Z        101010110    bit mask of new value

~Y       011001100    complement of y

~Y ^ Z   111011110    (1)

Y ^ X    100110111    (2)

(1)^(2)  100010110    this is the expected result