To save processing power (speed is vital, i have about 40 usec per loop) in my program Im using unsigned longs for the things that required that type, longs for numbers that could be both large and +/-, ints for medium sized numbers, and bytes for small numbers. In essence I'm trying to shrink the type to the smallest possible for what its going to store.
However, I need to do an if statement that looks like this:
if (unsignedLong-(int*byte) < long)
with the current setup. This wasn't working so i had to change the int to a long and then it worked...
I'm wondering how the proc (alu?) does the math. For example if I want to add a long and a int, does it buffer the int with 0's? Or does it chop off the long? In this case, does the order I add in matter then?
References to material covering this would be fine... this is totally new ground for me so I didn't even know what to google
flyingsilverfin:
To save processing power (speed is vital, i have about 40 usec per loop)
This will shave a few to several machine instructions off your loop...
void loop( void )
{
while ( true )
{
// your code goes here
}
}
However, I need to do an if statement that looks like this:
if (unsignedLong-(int*byte) < long)
with the current setup. This wasn't working so i had to change the int to a long and then it worked...
This also would have solved the problem (names changed in an attempt to add clarity)...
For example if I want to add a long and a int, does it buffer the int with 0's?
No. The int value is "sign extended" to a long.
Or does it chop off the long?
No.
In this case, does the order I add in matter then?
Possibly. The operands are first extended to the "largest" datatype of each operand. For example, when adding an int to a long the int is first sign extended to a long and then the addition is performed.
References to material covering this would be fine... this is totally new ground for me so I didn't even know what to google
"type conversion" "sign extension" "type promotion" ...and, of course... "c++"
The compiler already knows everything needed about the ALU. All the programmer needs is to understand how to talk to the compiler.
Looking at your conditional expression - (int*byte) will produce an int result. If the result doesn't fit into an int, then you can use a (long) cast to tell the compiler to expect a long-sized result.
unsignedLong - int could become dicey if the result is negative because your intention is ambiguous. Perhaps the unsignedLong should just be a long? ... Or should the int be an unsigned?
The missing vocabulary word (not very intuitive!) is "promotion".
The lds/sts are 2 clock cycles, the adds are 1.
12 x 2 + 4 = 28 cycles.
28 * 62.5 nS = 1.750 uS.
So a single add of two unsigned longs takes 1.750 uS. I made them volatile to force the compiler to generate code, you wouldn't normally do that. Anyway, you can see that you don't want to be doing much more than 20 such things inside loop, or you will exceed 40 uS.
However often enough when people ask very specific questions like this, it helps to know why there is this requirement. Perhaps the problem can be solved other ways (eg. timers, interrupts).
To save processing power (speed is vital, i have about 40 usec per loop) in my program Im using unsigned longs for the things that required that type, longs for numbers that could be both large and +/-, ints for medium sized numbers, and bytes for small numbers. In essence I'm trying to shrink the type to the smallest possible for what its going to store.