Large Decimal to Binary

HI Guys

I am trying to convert the following decimal number into binary.

51043465443420856213

The resuilt should be

10 1100 0100 0101 1110 1101 0001 0110 0001 1000 0100 0000 0110 1101 1111 1001
0101.

I am a newbie in Arduino .

Thanks

AFAIK the longest integer variable available on an Arduino is 64 bits (e.g. uint64_t). Your integer requires more than 65 bits so you're probably out of luck.
Let's try to avoid the old X/Y problem.
Why do you need to store such a large integer? What generates it? If you could store it, what would you do with the result?

There is an arbitrary precision arithmetic package. I haven't got a link for it but search for that phrase.

Pete

Perhaps the Big Number library can help.

I am trying to convert the following decimal number into binary.

How? Did you steal Harry Potter's magic wand? Or, do you actually have some code?

It would be interesting to see what data type you are storing 51043465443420856213 in, and whether you actually can (never mind that part; I already know).

you can't do it exactly unless you're willing to import or write a 72-bit/20-digit or better integer, BCD, or 'octuple' precision floating point math package. 19 decimal digits of accuracy is not easy to obtain.

otherwise... use "const float MY_BIG_NUMBER = 5.1043465E19;"

I tried everything and as you all know it didn't work. I tried float,double and long.

But off course float/double is only 32 bits. I did import big number library and that works fine for getting that number. Just not sure how to convert bignumber to bits.

wg0z:
otherwise... use "const float MY_BIG_NUMBER = 5.1043465E19;"

How can i conv this to bits?

How can i conv this to bits?

It's not worth trying. It will only have 6 or 7 digits of precision and your original number has 20.

But you still haven't said why you are trying to do this. For all we know, we're trying to solve the wrong problem.

Pete

el_supremo:
It's not worth trying. It will only have 6 or 7 digits of precision and your original number has 20.

But you still haven't said why you are trying to do this. For all we know, we're trying to solve the wrong problem.

Pete

Am I trying to implement a smart meter protocol called STS. The POS system generates the token which is the 20 digit decimal token. This then gets decrypted to get the meter number, amount of units to add, date purchased, which key the device is on etc.

Regards

This then gets decrypted to get the meter number ... etc.

decrypted or decoded?
i.e. are those different items such as meter number, encoded in a specific group of bits, or has the number been encrypted first?
If all you have to do is convert the big number to binary and extract different groups of bits, look up how to convert a decimal number to binary (or hex) and use the bignumber library to apply that technique to the 20-digit token.

Pete

el_supremo:
decrypted or decoded?
i.e. are those different items such as meter number, encoded in a specific group of bits, or has the number been encrypted first?
If all you have to do is convert the big number to binary and extract different groups of bits, look up how to convert a decimal number to binary (or hex) and use the bignumber library to apply that technique to the 20-digit token.

Pete

Hi Pete. Thanks. Went the same route and it works. Thanks

use a char or byte array...

isn't a string more than a number?

I’m assuming this is all strings.

First - this can’t be done in stages, because the very last decimal digit can affect the very first binary digit.

It might be possible, however, to do it in reverse.

Bah - too complicated. Just allocate an array of “enough” bytes, and implement two functions: add a number (where that number is < 256) and multiply by 10.

You work on each byte with a 16-bit int, and the top nybble becomes the carry of the next process.

/**
 * @dec - nul-terminated number
 * @bin - bytes for the result, little-endian
 * @binlen - size of bin. 
 */ 
void tobinary(char *dec, byte *bin, int binlen) {
  memset(bin, 0, binlen);

  while(*dec) {
    multiply(10, bin, binlen);
    add(*dec - '0', bin, binlen);
    dec ++;
  }
}

void add(unsigned n, byte *bin, int binlen) {
  for(int i = 0; i<binlen; i++) {
    n += bin[binlen];
    bin[binlen] = (byte)(n & 0xFF);
    n >>>= 8;
  }
}

void multiply(unsigned n, byte *bin, int binlen) {
  unsigned carry = 0;

  for(int i = 0; i<binlen; i++) {
    carry += ((int)bin[binlen]) * n;
    bin[binlen] = (byte)(carry & 0xFF);
    carry >>>= 8;
  }
}

The result array is little endian, so to print it off in order you need to iterate from binlen-1 to 0.

The OP said this was done/solved in msg #9.
So what's all the noise since then?

Pete

HI Guys

For anyone wondering here is how i did id.

String convertBigNumberToBinary(BigNumber bn){

BigNumber multiplier = BigNumber(16);
BigNumber remainder;
BigNumber result ;
String finalHex;
while(bn !=0){
result = bn / multiplier;
remainder = bn - (result * multiplier);
Serial.println(remainder);
Serial.println(String((int)remainder,BIN));
String newString = padLeft(String((int)remainder,BIN));

newString.concat(finalHex);
finalHex = newString;
bn = result;
Serial.println(finalHex);
}
return “test”;
}

String padLeft(String str){
while(str.length() < 4){
String zeroString = “0”;
zeroString.concat(str);
str = zeroString;
}
return str;
}

mariusvstraaten:
HI Guys

For anyone wondering here is how i did it. …

If you ever start running low on memory in that sketch it’s really not all that difficult to do it without any libraries. The basic algorithm is just successive divides by two.

My code does it with no libraries, 9 lines of code to do the long divide2/modulo2 and just one line of code to do the actual binary conversion.

I didn’t store the results efficiently though, using one byte per bit of the binary expansion. But that could easily be packed on the fly with a few extra lines code.

char longDec[21] = "51043465443420856213";
byte longBin[70];

byte charDivMod2(char* ld) {
  //  ld is numerical string representing long decimal integer;
  //  performs ld = ld div 2;
  //  returns ld mod 2;
  byte writePosition = 0, readPosition = 0, carry = 0, tmp;
  while (ld[readPosition]) {
    tmp = ld[readPosition] - '0' + 10 * carry;
    carry = tmp % 2;
    tmp = tmp / 2;
    if (tmp != 0 || readPosition != 0) ld[writePosition++] = tmp + '0';
    readPosition++;
  }
  ld[writePosition] = 0;
  return carry;
}

void setup() {
  byte k = 0;
  Serial.begin(9600);
  Serial.println(longDec);

  // Calculate binary as array of bytes
  while (longDec[0]) longBin[k++] = charDivMod2(longDec);

  // Show results
  for (int i = 0; i < k; i++) Serial.print(longBin[k - 1 - i]);
}

void loop() {
  // put your main code here, to run repeatedly:
}
1 Like