0
volatile long pakiet = 0;
String longToBinaryString(long num)
{
  String result = "";
  for (int i = 31; i >= 0; i--)
  {
    if ((num >> i) & 1)
    {
      result += "1";
    }
    else
    {
      result += "0";
    }
  }
  return result;
}


bool isNumber(String str)
{
  for (int i = 0; i < str.length(); i++)
  {
    if (!isdigit(str.charAt(i)))
    {
      return false;
    }
  }
  return true;
}

long readBinaryString(char *s) {
  long result = 0;
  while (*s) {
    result <<= 1;
    if (*s++ == '1') result |= 1;
  }
  return result;
}

long binaryToLong(String binaryString) {
  long result = 0;
  for (int i = 0; i < binaryString.length(); i++) {
    if (binaryString.charAt(i) == '1') {
      result += pow(2, binaryString.length() - i - 1);
    }
  }
  return result;
}

void setup() {
  Serial.begin(115200);
  Serial.println("yo");
}

void loop() {


  if (Serial.available() > 0)
  {
    String message = Serial.readStringUntil('\n');
    message.trim();
    if (isNumber(message) and message.length() == 32)
    {
      char charArray[33];
      message.toCharArray(charArray, 33);
      Serial.print("What enter the function: ");
      Serial.println(charArray);
      pakiet = readBinaryString(charArray);
      Serial.print("Thats exit the function: ");
      Serial.println(pakiet);
      Serial.print("Thats the reverse of the function: ");
      Serial.println(longToBinaryString(pakiet));
    }

    if (isNumber(message) and message.length() == 32)
    {
      Serial.print("What enter the function: ");
      Serial.println(message);
      pakiet = binaryToLong(message);
      Serial.print("Thats exit the function: ");
      Serial.println(pakiet);
      Serial.print("Thats the reverse of the function: ");
      Serial.println(longToBinaryString(pakiet));
    }
  }
}

The problem is the result.

I want to get same result for example data: '11111111000011111111111111000011'

Results are

  • 14:56:45.162 -> What enter the function: 11111111000011111111111111000011
  • 14:56:45.162 -> Thats exit the function: -15728701
  • 14:56:45.162 -> Thats the reverse of the
    function: 11111111000011111111111111000011
  • 14:56:45.162 -> What enter the function: 11111111000011111111111111000011
  • 14:56:45.162 -> Thats exit the function: -1089471104
  • 14:56:45.162 -> Thats the reverse of the function: 10111111000011111111110110000000

I want to make function that uses strings, to work as expected and be reversable.

Why function that using String is working differentyl than with *char aray?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • `result += "1";` This looks like C++ ;) – Jason Apr 05 '23 at 13:07
  • 4
    Avoid `pow()` for integer arithmetic, and obtain powers of 2 by shifting. See [Strange behaviour of the pow function](https://stackoverflow.com/questions/18155883/strange-behaviour-of-the-pow-function) – Weather Vane Apr 05 '23 at 13:19
  • 2
    Any particular reason why you can't use built-in C++ functions for this, such as `to_string`? I mean sure, C++ will explode across your tiny MCU's memory and destroy everything, but you (or rather the goofballs who invented Arduino) already made that call, so might as well take advantage before the unavoidable out of memory disaster strikes. – Lundin Apr 05 '23 at 13:28
  • The difference does not depend on the string representations but on your different calculations. You can use the same method as in the `char*` version. – molbdnilo Apr 05 '23 at 13:35
  • Example data must be binary with lenght of 32. Thats why i can't use '.toInt()' – MarcinanBarbarzynca Apr 05 '23 at 13:50

3 Answers3

1

Don't use pow and other floating-point operations in integer problems.

Here's one solution that should look familiar:

long binaryToLong(String binaryString) {
  long result = 0;
  for (int i = 0; i < binaryString.length(); i++) {
    result <<= 1;
    if (binaryString.charAt(i) == '1') {
      result |= 1;
    }
  }
  return result;
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
0

As already mentioned by @Weatherr Vane in the comments, pow() can give some strange behaviour.

I would take another approach and reuse your already functional readBinaryString() by first utilizing the String function toCharArray().

long binaryToLong(String binaryString) {
  char charArray[33];
  binaryString.toCharArray(charArray, 33);
  long result = readBinaryString(charArray);
  return result;
}
Robin Hellmers
  • 214
  • 1
  • 11
0
long readBinaryString(char *s) {
  long result = 0;
  while (*s) {
    result <<= 1;
    if (*s++ == '1') result |= 1;
  }
  return result;
}

long binaryToLong(String binaryString) {//Just cast it to char array.
  char charArray[binaryString.length()+1];
  binaryString.toCharArray(charArray, binaryString.length()+1);
  long result = readBinaryString(charArray);
  return result;
}

As Robin Hellmers posted Yes. That solves the problem.