Help with pow()

See sketch below: when calculating powers of 2, pow() is always off by 1 (for values > 1). What am I overlooking? I am using arduino-0012, on Linux, x86_64.

Output of sketch:

1
2
3
7
15
31
63
127
255
511

#define NUM 10

float i;
long x;

void setup() {
  Serial.begin(9600);
}


void loop() {
  for (i = 0; i < NUM; i++) {
    x = pow(2, i);
    Serial.println(x);
  }
}

the standard 'pow()' function returns a floating-point value, and I assume the Arduino one does, too. Your code then assigns that to a long integer variable, which implicitly truncates it. I think you'll need to look for a rounding function, or maybe add 0.5 in f.p. before truncating:

x = pow (2, i) + 0.5;

Ah, yes. You're right.
Much better this way. If Serial.println() would have accepted a float without having o resort to tricks, I might have found out earlier :wink:

Using pow() to find integer powers of two is pretty silly.

For exact integer values, the expression (1 << n) will give you 2n much faster, up to the limit of whatever integer type you give. For example, (1 << 12) == 4096. You can read that expression as "one shifted left twelve times." It's a binary 1 followed by 12 zeroes.

For floating point values, you can store larger powers, but it's basically storing the (1, n) as the (mantissa, exponent). You could just store n as an integer and have an even wider range.

Thanks, halley. I'm looking into that now.

[OT]
I have a (byte) array of 31 zeros and ones, and want to convert that to a hex number.
So what I'm doing is first convert them to a decimal value in a for loop (<<), then convert that to HEX using itoa.
There probably is a more efficient way, but I only just started programming C/Arduino, so there's a lot to pick up on :wink:
[/OT]

Hope you don't mind me walking through your problem (as I understand it).

You have an array of 32 bytes, each using only the values 0 or 1. Right? You could think of that using this sort of syntax. (If you really only have 31, not 32, this becomes much easier if you actually add a zero at the left end, to make it 32, a number divisible by four.)

byte mybits[32] = { 1,0,0,1,  0,1,1,0,  1,1,0,0,  0,0,0,1,  . . . };

You want to print the binary as hexadecimal digits? A hexadecimal digit represents four bits, called a nibble or nybble. You want to squish four 1-or-0 bytes into four bits. So 1,0,0,1 turns into binary 1001 (or hexadecimal 9). And so on. Right?

You're on the right track, cramming powers of two. But you only need four at a time. If the four bytes are a,b,c,d, then to get the nibble value:

nibble = (a<<3) + (b<<2) + (c<<1) + d;

Once you have a nibble value from hexadecimal 0 to hexadecimal F, you can convert that nibble to a character ready for printing directly.

static const char* _hexdigits = "0123456789ABCDEF";

Now _hexdigits[nibble] gives you the printable character for the nibble value.

Lastly, we loop through the bigger array of bytes you have.

for (int i = 0; i < 32; i += 4)
{
    int nibble = (mybits[i] << 3);
    nibble += (mybits[i+1] << 2);
    nibble += (mybits[i+2] << 1);
    nibble += (mybits[i+3]);
    Serial.print(_hexdigits[nibble]);
}

That's exactly what I was looking for. Thank you very much! That will save me a couple of hours :wink:

I had digital math a long time ago in school, I now notice it has become a little rusty wry smile But I love doing this kind of stuff, so it's all OK.