You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino中String与char数组转long结果不一致问题及修正需求

32位二进制字符串转long的问题与修复
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));
    }
  }
}

我在Arduino中实现了两种32位二进制字符串转long的方法:基于char数组的readBinaryString,以及基于String类的binaryToLong,同时用longToBinaryString实现long转32位二进制字符串的逆向验证。

输入二进制字符串11111111000011111111111111000011时,两种方法结果差异明显:

  • readBinaryString转换结果为-15728701,逆向转换后与原输入一致;
  • binaryToLong转换结果为-1089471104,逆向转换后得到10111111000011111111110110000000,与原输入不符。

结果不同的原因

binaryToLong的问题出在使用了pow()函数。pow()是浮点数运算函数,而long是整数类型。当计算pow(2, n)(尤其是n接近31时),浮点数无法精确表示大整数,会产生精度误差。比如pow(2,31)的计算结果可能不是精确的2147483648,而是一个近似值,转成long时就会出错。再加上用+=累加这些不精确的值,最终结果完全偏离正确值。

而readBinaryString采用位运算:每次将结果左移1位(等价于乘以2),遇到'1'就给最低位设为1。整个过程都是整数操作,没有精度损失,因此结果正确。

修正后的binaryToLong函数

将binaryToLong改成位运算实现,逻辑与readBinaryString一致,适配String类:

long binaryToLong(String binaryString) {
  long result = 0;
  for (int i = 0; i < binaryString.length(); i++) {
    result <<= 1; // 左移一位,等价于乘以2
    if (binaryString.charAt(i) == '1') {
      result |= 1; // 最低位设为1
    }
  }
  return result;
}

修正后,该函数的转换结果与readBinaryString完全一致,逆向转换也能得到原输入的二进制字符串。

内容的提问来源于stack exchange,提问作者MarcinanBarbarzynca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:37:41