Well, here’s my library:

```
#include "Arduino.h"
inline boolean bcdBadL (unsigned long x) {
// check all EXCEPT high nibble
return (((x ^ (x+0x06666666)) & 0x11111110) != 0);
}
inline unsigned long bcdAddL (unsigned long x, unsigned long y) {
// no sanity checking of input
// "out of range" results are e.g. A0000000 for 100 million
unsigned long binsum = x + y;
unsigned long carry = ((binsum + 0x06666666) ^ x ^ y) & 0x11111110;
return (binsum + ((carry>>2) | (carry>>3)));
}
inline unsigned long bcdSubL (unsigned long x, unsigned long y) {
// no sanity checking of input
// "negative" results are e.g. F9999999 for -1
unsigned long bindiff = x - y;
unsigned long borrow = (bindiff ^ x ^ y) & 0x11111110;
return (bindiff - ((borrow>>2) | (borrow>>3)));
}
inline unsigned long bcdTwiceL (unsigned long x) {
// no sanity checking of input
unsigned long adj = (x + 0x03333333) & 0x08888888;
return (x << 1) + adj - (adj >> 2); // magic here
}
inline unsigned long bcdTenfoldL (unsigned long x) {
// because of the way we use the high nibble, this is nontrivial
unsigned long highpart = x & 0xF0000000;
return ((highpart<<3) + (highpart<<1)) + (x<<4);
}
unsigned long bcdMultL(unsigned long x, unsigned long y) {
// this function multiplies two BCD numbers by means of
// BCD addition, subtraction, doubling, multiplication by ten,
// and a little extra magic
unsigned long total = 0;
byte d = 0;
unsigned long twice = 0;
while (true) {
d = (15&(byte)y);
if (d&1) total = bcdAddL(total,x);
if (d>1) {
twice = bcdTwiceL(x);
if (d&2) total = bcdAddL(total,twice);
if (d&4) total = bcdAddL(total,bcdTwiceL(twice));
if (d&8) {
total = bcdSubL(total,twice);
y += 8; // magic
if (!(0xF0&(byte)y)) y |= 0x60; // more magic
}
}
y >>= 4;
if (!y) return total;
x = bcdTenfoldL(x);
}
}
```

And here’s what I was trying to run:

```
#include "bcd.h"
unsigned long index = 0x0;
unsigned long count;
unsigned long result;
void setup() {
Serial.begin(9600);
Serial.println("Calculation of pyramidal numbers");
Serial.println("I define the nth pyramidal number as");
Serial.println("1*1 + 2*2 + 3*3 + ... n*n");
Serial.println();
}
void loop () {
index = bcdAddL(index, 0x1);
result = 0x0;
for (count = 0x1; count <= index; count = bcdAddL(count, 0x1)) {
result =bcdAddL(result, bcdMultL(count, count));
}
Serial.print(index,HEX);
Serial.print(" ");
Serial.println(result,HEX);
delay(800);
}
```

And as for “crazy”:

Sketch #5 works all right.

Sketch #6 goes crazy.

And by “crazy” I mean “produces wildly wrong answers”. I’m not at home now, so I’ll have to post the crazy output some other time.