[sdiy] help...no make8() function in Arduino...converting PIC to AVR

Ove Ridé nitro2k01 at gmail.com
Wed Apr 11 19:17:12 CEST 2012


On 11 April 2012 18:47, dan snazelle <subjectivity at hotmail.com> wrote:
> ok so if
>
>
>  make8  = (((var >> (offset*8)) & 0xff)
>  _mul  value = (int)( a1*val1>>8);
>
> then since i dont quite understand the parentheses in define I could make 2 functions

No! Let's try to understand what's going on instead!
The rule is simple.
"Write your expression as you want it to behave, then add a
parenthesis around every parameter, as well as a parenthesis around
the whole expression."

Why? Because it's just a string operation. A C preprocessor macro just
literally put the string of what you're giving it inside the
expression.

Let's look at a couple of example to understand why you need to do this.

#define multiply(x,y) x*y

Simple right? Let's see how it behaves...

answer = multiply(3+something,4+something_else);

What you give the function is plugged right in, and this is what the
compiler sees and compiles.

answer = 3+something*4+something_else;

You can see the problem. something is multiplied by 4, which is not
what you intended. Add inner parentheses and you'll be alright.

#define multiply(x,y) (x)*(y)
answer = multiply(3+something,4+something_else);
answer = (3+something)*(4+something_else);

Let's try something different...

#define add(x,y) (x)+(y)

You can probably see where this is going...

answer=add(something,something_else)*42;

this translates to:

answer=(something)+(something_else)*42;

Again, operator precedence screws you over, because only the second
term is multiplied 42, and not the whole expression as intended. The
fix is to put parentheses around the whole thing:

#define add(x,y) ( (x)+(y) )
answer=add(something,something_else)*42;
answer=((something)+(something_else))*42;


> byte make8(int var, byte offset)
> {
> byte result=(((var >> (offset*8)) & 0xff);
> return result;}
>
> and for the other function  (_mul)
>
>
> int _mul (byte a1, byte val) {
>
> int result=(int)( a1*val1>>8);
> return result;
> }
>
> do those look right?

I would avoid using functions, as they incur a small overhead in
making the function call, as opposed to a simple mathematical
expression. But since you asked, no, your _mul is incorrect, I
believe. If I recall correctly, shift oeprations are processed before
multiplications, so your expression would in practice be executed as:
( a1*(val1>>8)) which would guarantee that val1 is always zero because
all of its bits are shifted away!
int result=(int)( (a1*val1)>>8);
HOWEVER this is not even what the function does!!! (This was one of
two initial guesses, and it was wrong.) _mul is apparently just a
simple multiplication. So, after applying the rule above, you start
with

#define _mul(x,y) x*y
And then add inner and outer parentheses to get:
#define _mul(x,y) ( (x)*(y) )

-- 
/Ove

Blog: <http://blog.gg8.se/>

"Here is Evergreen City. Evergreen is the color of green forever."



More information about the Synth-diy mailing list