Exponentiation, pow(x, y) question

Since there is no "exponentiation" operator, I have to use pow(). But that gives a result as a double, and I want a byte result.

I want to map the bits of bytes (bit0 thru bit7) to pins 2 thru 9

Does the syntax of this function look correct, it certainly compiles ok

void databus(byte value) {
// outputs the data byte to pins 2 to 9
  // i : 0 to 7
  // pin to write to : 2 to 9

  for (byte i=0; i<8; i++) {
    digitalWrite(i+2, value & byte(pow(2, i)));  
  }
}

Don't use pow() for powers of two.

It's a bazooka flyswatter, and just about as accurate.

Hint: if it compiles, the syntax is correct. The semantics need some work.

i+2 is a terrible way to address pins. There will always be reasons why you cannot use 8 pins in a row in a real project. Maybe you need pin2's interrupt ability or you need a PWM pin for analogWrite(). Use an array:

const int busPins[] = [2,3,4,5,6,7,8.9];

This is part of some communication bus? How is the data clocked out of the bus? If the receiver sees the first pin change, it may grab the rest of the values before your loop has written them. digitalWrite() is relatively slow. You could look into using a "port write" to write all 8 bits simultaneously.

TheMemberFormerlyKnownAsAWOL:
Don't use pow() for powers of two.

It's a bazooka flyswatter, and just about as accurate.

Hint: if it compiles, the syntax is correct. The semantics need some work.

Great answer, not !

Delta_G:
For powers of 2 just use a bitshift.

for (byte i=0; i<8; i++) {

digitalWrite(i+2, value & (1 << i));
  }

That gives me something to consider....

MorganS:
i+2 is a terrible way to address pins. There will always be reasons why you cannot use 8 pins in a row in a real project. Maybe you need pin2's interrupt ability or you need a PWM pin for analogWrite(). Use an array:

const int busPins[] = [2,3,4,5,6,7,8.9];

This is part of some communication bus? How is the data clocked out of the bus? If the receiver sees the first pin change, it may grab the rest of the values before your loop has written them. digitalWrite() is relatively slow. You could look into using a "port write" to write all 8 bits simultaneously.

There is no "clocking" needed. The "receivers" are simple 8-bit "D" type latches. I simply have to present the 8-bit data onto the pins and then pulse the "LE" to them. I can see no reason why "i+2" is a bad way to address the pins. I control when the data is transferred from the "D" inputs to the "Q" outputs with a "Latch Enable" (LE) output.

All that is needed is to pre-code (or build) the data to the data-bus pins, then pulse the "LE" on another pin, in this case pin 10 for the display segment drivers, and pin 11 for the cathode drivers. It does not matter how long it takes to output the data onto the 74HC573 inputs, they are transferred to the "Q" outputs on "LE" transition low to high.

The display board I am testing circuit is here...

MorganS:
Use an array:

const int busPins[] = [2,3,4,5,6,7,8.9];

Perhaps you mean:

const int busPins[] = {2,3,4,5,6,7,8,9};

TheMemberFormerlyKnownAsAWOL:
Don't use pow() for powers of two.

This is what happens when you do: Weird but true pow(x,y) function - Frequently-Asked Questions - Arduino Forum
(TL;DR: Don't use pow() with integers. It can give you wrong answers.)

You probably don't want to even use pow() with a floating point base and a "small integer" exponent (squared, cubed, most common curve-fit polynomials.)
It essentially uses exp(log(x)*y) which is likely to be slower than "several" floating point multiplications, though the exact crossover point is probably "complicated."

If you have to, write your own version:

byte ipow(byte x, byte y) {
  byte r=x;
  while (--y)
    r*=x;
  return r;
}

(although in this case, you certainly want "shift" instead.)

westfw:
You probably don't want to even use pow() with a floating point base and a "small integer" exponent (squared, cubed, most common curve-fit polynomials.)
It essentially uses exp(log(x)*y) which is likely to be slower than "several" floating point multiplications, though the exact crossover point is probably "complicated."

If you have to, write your own version:

byte ipow(byte x, byte y) {

byte r=x;
  while (--y)
    r*=x;
  return r;
}





(although in this case, you certainly want "shift" instead.)

Forgive me for asking ....

while (--y)

What does that mean ?

and

r*=x

What does that mean ?

I've searched, but cannot find....

daba:
Forgive me for asking ....

while (--y)

What does that mean ?

and

r*=x

What does that mean ?

I've searched, but cannot find....

It is here:


Fig-1:

1. --y?

Let us say: y =5

while(--y) ==> while(4)
y = 4

while(y++) ==> while(5)
y = 6


[b]2.[/b]  r *=x ?
Try yourself with the help of Fig-1.

--y means "decement y, and then use the new value"
r*=x means "multiply r by x (new value stays in r. Short for r=r*x;

Perhaps you mean:

const int busPins[] = {2,3,4,5,6,7,8,9};

or even

const byte busPins[] = {2,3,4,5,6,7,8,9};

westfw:
--y means "decement y, and then use the new value"
r*=x means "multiply r by x (new value stays in r. Short for r=r*x;

Or, short for:

y = r*x;  
 r = y;

westfw:
If you have to, write your own version:

byte ipow(byte x, byte y) {

byte r=x;
  while (--y)
    r*=x;
  return r;
}

If you want it to work for y == 0:

/// base ^ exp
uint8_t pow(uint8_t base, uint8_t exp) {
    uint8_t result = 1;
    while (exp-- > 0)
        result *= base;
    return result;
}

/// 2 ^ exp
uint8_t pow2(uint8_t exp) {
    return 1 << exp;
}

Pieter

I suppose if it’s to do bit shifting, it really ought to support 0 as an exponent...

daba:
There is no "clocking" needed. The "receivers" are simple 8-bit "D" type latches. I simply have to present the 8-bit data onto the pins and then pulse the "LE" to them. I can see no reason why "i+2" is a bad way to address the pins.

LE is the clock pin in this context. It sounds like you are in control of the timing issues, so no problem there.

I can see that the reason why you see no problem is because you haven't built the final version yet. Any hardware more complex than about 4-8 wires will always change between the first version and the last.