在Keil中怎样避免系统自动将无符号值改为有符号值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Keil中怎样避免系统自动将无符号值改为有符号值相关的知识,希望对你有一定的参考价值。

比如
uint a;
if(a>0x8000)系统往往会把0x8000看做有符号值

放心吧系统不会把无符号数改为有符号数的,只会在无符号数与有符号数混合运算时,先把有符号数改为无符号数,再进行运算。例如你举的例子改为if(a>-1)会自动把-1看成0xFFFF的;而不会把if(a>0xFFFF)中的0xFFFF改为-1;
不同数据类型之间的运算转换规律如下:char、short->int->unsigned->long->double<-float追问

然而事实是我就碰到了这个问题,比如:ulong a; a=100;if(a<0xffff)结果1;else结果2;运行后发现
竟然是结果2,后来我把0xffff改成65535但有时还会出错,变成if(a<0x7fff)后就变的正常了,还有一个问题我把Keil中的优化级别由8级改为6级时编译不能通过。请教高手指点。

参考技术A 最简单最直接多敲几个字符的方法: 强制类型转换追问

可不可以说的具体点,谢谢了,我有时不得不在每个参与比较的变量前加上变量定义,即
if((uint )a>(uint) b)

如何将无符号字符数组存储为浮点值?

【中文标题】如何将无符号字符数组存储为浮点值?【英文标题】:How to store a unsigned char array to float value? 【发布时间】:2019-05-07 06:30:42 【问题描述】:

我正在尝试使用 RS232 串行通信从 Arduino 和 Raspberry Pi 获取传感器数据。我已经搜索了这个小东西,并在下面的链接中找到了一些相关的东西,但无法得到完整的想法。

操作系统(内核)有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且串行端口上有新字符到达,则缓冲区中最旧的字符将被覆盖,因此将丢失。成功调用 RS232_OpenComport() 后,操作系统将开始缓冲传入的字符。

这些值正确地从 Arduino 传到 Raspberry Pi(输出附在下面),它存储在指向 unsigned char[] 的指针中,该指针定义为 unsigned char *buf[4096]。

int main()

  int i, n,
      cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
      bdrate=9600;       /* 9600 baud */

  unsigned char buf[4096];

  char mode[]='8','N','1',0;

  while(1)
  
    n = RS232_PollComport(cport_nr, buf, 4095);

    if(n > 0)
    
      buf[n] = 0;

      for(i=0; i < n; i++)
      
        if(buf[i] < 32)  /* replace unreadable control-codes by dots */
        
          buf[i] = '.';
        
      

      printf("received %i bytes: %s\n", n, (char *)buf);
    

现在我想将这些值存储在另一个浮点/双精度变量中,以便我可以对其执行进一步的操作。如何存储一个值假设 0.01 到一个浮点数/双精度数,稍后用于创建东西。

【问题讨论】:

尝试在 cppreference.com 或 cplusplus.com 上查找 atof/atod/strtod 在这里回答:***.com/questions/1012571/… 如果您的数据包含多个数字,您只需先将数字分开即可。 @Ptaq666 你能详细说明一下吗,我不知道到底是什么。 std::string to float or double的可能重复 @uvan ,在答案中详细说明。现在明白了吗? 【参考方案1】:

从屏幕截图中的输出看来,您发送的是数字的字符串表示形式,而不是实际数字。您只需要检测那些刚刚用. 替换的“不可读控制代码”,因为它们可能会告诉您一个数字何时结束而另一个数字何时开始。只需让QSerialPort * serial; 成为适当的班级成员。

另外,检查打开端口时的错误:serial-&gt;open(QIODevice::ReadWrite); 然后,在serialreceived() 中插入一些qDebug() 以查看是否调用了插槽以及canReadLine() 是否有效。您应该使用QByteArray 来读取您的数据。如果响应中有任何不符合字符串的字符,则生成的QString 将被提前终止,请使用readLine() 而不是readAll(),如下所示:

QByteArray data = serial -> readLine();
qDebug() < data.toHex(' '); // prints the hex representation of your char array
QString str(data);
qDebug() << str;

【讨论】:

【参考方案2】:

首先,最好使用其他 ASCII 字符(例如空格)来分隔数字,因为. dot 是浮点数的一部分。然后,您可以从原始unsigned char 数组构造std::string 对象,将其拆分为多个字符串并将每个string 转换为float

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

int main() 
    // imagine that this buff is already after read and preprocessing
    unsigned char buff[1024] = "13.60  13.60  -11.12  -0.3  and let's say that the rest is garbage";
    int n = 28;  // let's say that you received 28 bytes
    std::string strBuff(reinterpret_cast<char*>(buff), n); // construct a string from buff using just first 28 bytes
    std::vector<std::string> numbers;
    boost::split(numbers, strBuff, boost::is_any_of(" "), boost::token_compress_on);
    for (const auto& n : numbers) 
        try 
            std::cout << std::stof(n) << std::endl;
         catch (const std::exception& e) 
            std::cout << n << " is not convertible to float: " << e.what() << std::endl;
        
    
    return 0;

我采用了this answer 的字符串拆分方法,但你可以使用任何适合你的方法。

我使用reinterpret_cast 是因为std::string 接受char 而不是unsigned char 作为CTor arg。

【讨论】:

它是用于无符号字符缓冲区的,但我已经采取了(Buf 是一个指向缓冲区的指针,并且大小缓冲区的大小以字节为单位)。在这种情况下,我该如何转换?将接收到的字符数返回到缓冲区中。

以上是关于在Keil中怎样避免系统自动将无符号值改为有符号值的主要内容,如果未能解决你的问题,请参考以下文章

将无符号字节流转换为有符号字节流 Golang

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

如何从 Python 将无符号值发送到 dBus

将无符号整数存储在指针中

将无符号字符读入字符串

将无符号整数输入属性传递给顶点着色器