Hello, I am trying to get my Arduino to print the Fibonacci sequence but after it gets to the 22nd number (28657) it starts printing negative numbers. Does anyone else have this problem? if you know anything that would help it would be greatly appreciated.
When I ran it, it stopped here:
29941786242203757034937742679847722285930070850760053628857379482552272854210034290353600980959455084033350473690872688601978897187669305042631491407198434363333507958485382908014045060473022993091179846948416491187003494754
I added a bit of code to show an iteration count and it stopped at the same place, iteration 1069.
Since the calculation only involves adding two integers, and the hardest (and slowest) part will be the division needed to convert from binary to decimal for printing, I though I'd try doing it with binary coded decimal. Using two large arrays to hold the numbers, and overwriting the smallest number with the sum to avoid using a third array, I was able to get 8421 iterations on an UNO giving a 1760 digit number, and slightly over 37,000 iterations on a Mega. Surprisingly fast, a bit over six minutes on a Mega when printing every thousandth result.
//const size_t arraySize = 3868; //array to hold 7736 BCD digits on a mega, a bit over 37000 iterations
const size_t arraySize = 880; //array to hold 1760 BCD digits on an UNO, 8421 iterations
uint8_t num1[arraySize];
uint8_t num2[arraySize];
uint16_t loopcount = 0;
uint8_t* bcd1;
uint8_t* bcd2;
uint8_t* bcdTemp;
void setup() {
Serial.begin(115200);
//set num1 = 0, num2 = 1
for (size_t i = 0; i < sizeof(num1); i++) {
num1[i] = 0;
num2[i] = 0;
}
num2[sizeof(num2) - 1] = 1;
Serial.print(F("0:"));
printBCD(num2, arraySize);
bcd1 = num1;
bcd2 = num2;
}
void loop() {
addBCD(bcd1, bcd2, arraySize);
loopcount++;
if ((loopcount % 1000) == 0) {
Serial.print(loopcount);
Serial.print(':');
printBCD(bcd1, arraySize);
Serial.print(F("millis: "));
Serial.println(millis());
}
if ((bcd1[0] >> 4) > 4) { //stop when doubling the number would cause overflow
Serial.print(F("terminated at: "));
Serial.println(loopcount);
printBCD(bcd1, arraySize);
Serial.print(F("millis: "));
Serial.println(millis());
while (true) {};
}
//swap digits
bcdTemp = bcd1;
bcd1 = bcd2;
bcd2 = bcdTemp;
}
void addBCD(uint8_t* bcd1, uint8_t* bcd2, size_t bcd_size) {
//add bcd1 to bcd2, storing result in bcd1
uint8_t carry = 0;
uint8_t lowerBCD;
uint8_t upperBCD;
for (size_t i = 0; i < bcd_size; i++) {
size_t index = bcd_size - i - 1;
lowerBCD = (bcd1[index] & 0x0F) + (bcd2[index] & 0x0F) + carry;
if (lowerBCD > 9) {
lowerBCD = lowerBCD - 10;
carry = 1;
} else {
carry = 0;
}
upperBCD = (bcd1[index] >> 4) + (bcd2[index] >> 4) + carry;
if (upperBCD > 9) {
upperBCD = upperBCD - 10;
carry = 1;
} else {
carry = 0;
}
bcd1[index] = (upperBCD << 4) | lowerBCD;
}
}
void printBCD(uint8_t* bcd, size_t bcd_size) {
uint16_t numDigits = 0;
bool leadingZero = true;
for (size_t i = 0; i < bcd_size; i++) {
byte upperBCD = bcd[i] >> 4;
byte lowerBCD = bcd[i] & 0x0f;
if (leadingZero && !(upperBCD == 0)) {
leadingZero = false;
}
if (!leadingZero) {
Serial.write('0' + upperBCD);
numDigits++;
}
if (leadingZero && !(lowerBCD == 0)) {
leadingZero = false;
}
if (leadingZero && (i == bcd_size - 1)) {
leadingZero = false;
}
if (!leadingZero) {
Serial.write('0' + lowerBCD);
numDigits++;
}
}
Serial.print(F("\nnumber of digits: "));
Serial.println(numDigits);
}
@coderturkey I hope you don't mind that we got a little carried away. I like the Wokwi simulator and I like the BigNumber library, so this was an interesting test.