Arduino Math using Nano

The following code works and gives me the long long result that i wanted. It isn't pretty, but at least I can move on to other tasks. Thanks to all who helped.

unsigned long long ReceiverFreq = 147165000;
char strfreq[11];     // empty string
char *ptr = strfreq; //

void setup()

{
  Serial.begin(57600);
  ReceiverFreq = ReceiverFreq - 10700000;
  ReceiverFreq = ReceiverFreq / 3 ;
  //ReceiverFreq = 454883300; // this is what I want to send to my si5351
  ltoa(ReceiverFreq, strfreq, 10);
  String zeros = "00";
  String  FinalFreq = strfreq + zeros ;
  FinalFreq.toCharArray(strfreq, 11);

  ReceiverFreq = char2LL(ptr);
  Serial.println();
  Serial.println("rec freq ");

  printULL(ReceiverFreq);

}

void loop() {

}
void printULL(unsigned long long value)
{
  if (value == 0)
    return;
  printULL(value / 10);
  Serial.print(int(value % 10));
}
long long char2LL(char *str)
{
  long long result = 0; // Initialize result
  // Iterate through all characters of input string and update result
  for (int i = 0; str[i] != '\0'; ++i)
    result = result * 10 + str[i] - '0';
  return result;
}

The following printULL() subroutine of post #15 works well for value > 0. If the passed value is 0, it can't be printed. How can 0 be printed?

void printULL(unsigned long long value)
{
  if (value == 0)
    return;
  printULL(value/10);
  Serial.print(int(value % 10));
}

That is left as an exercise for the reader.

Noted down!

void printULL(uint64_t value) {
  if (value) {
    for (uint64_t v = 10000000000000000000ull; v; v /= 10) {
      if (v <= value) {
        Serial.print((int)(value / v % 10));
      }
    }
    return;
  }
  Serial.print(0);
}

Less elegant, but nice when you are short on stack space.

Tested for 0, 1, and 18446744073709551615; your subroutine is working fine!
Congratulation!

Sweet. Thank you.

What is about the following one?

void printULL(uint64_t value)
{
  int i = 0;
  byte myBCD[25];

  do
  {
    myBCD[i] = value % 10;
    value = value / 10;
    i++;
  }
  while (value != 0);
  for (int j = i - 1; j >= 0; j--)
  {
    Serial.print(myBCD[j]);
  }
}

It is sort of the reverse of the previous one.

Both you and @johnwasser have used % and / operators to extract the BCD digits and then just print them on the Serial Monitor. I have also used the same operators and the attempt came on the way of trying to understand @jfjlaros and @johnwasser program logic.

Well, it certainly works.

Nope.

I know you are obsessed with BCD, but this problem has nothing to do with BCD.

I mean --
Given:

byte y = 0x35;  //53
byte r1 = y%10; //r1 = 00000011 = unpacked BCD

Again nope.

For BCD you would mask and shift, not divide by ten.

So you basically fell for an incorrect comment?
Or did you make that comment yourself?

I have done the modulus (%) operation and not the division (/) to get the unpacked BCD.

You are using the remainder of the division, so you divide.

No, you don't get any unpacked BCD.

I think the obsession and the missing understanding of BCD is a strange combination.

% operator is doing the above task; as a result, I get 00000011 and 00000101 from 0x35.

byte y = 0x35;
byte r1 = y%10;   //r1 = 00000011
y = y/10;
byte r2 = y%10;  //r2 = 00000101

There is a division involved in getting the remainder.

BTW 0x35 would yield "35" if it really was BCD.

A BCD number, by definition, is a 4-bit binary for the decimal digits: 0 to 9. If we want to store them into computer memory, they have to be formatted into 8-bit unpacked (like 00000011 and 00000101) BCD numbers or packed BCD numbers (like 00110101 or 01010011).

65535 (to my eyes it is a decimal number) can be stored in computer memory as:

1111 1111 1111 1111 (the binary format)

binary2

or

0110 0101 0101 0011 0101 (the BCD format)

bcd3byte

Nope, BCD is a coding that uses only 0-9 for the digits, but 16 as the base.

The problem was the conversion of a long long binary into decimal representation.

Have a nice day and don't see BCD anywhere you see decimal digits.

1 Like