Arduino上的十六进制乘法

时间:2014-04-15 12:02:16

标签: c++ arduino

我已经用高级动态类型语言编写了很长时间,但我刚刚开始使用C ++(在Arduinos上)。我正在尝试编写一个函数,将int0之间的3个0xFF(RGB颜色值)转换为单个unsigned long,最多可达{{1} }}。无符号长整数可以达到0xFFFFFF,因此应该有效。

我在我的个人计算机上编写了以下测试,并使用0xFFFFFFFF编译了它:

g++

正如预期的那样输出:

#include <iostream>
using namespace std;

int main(){
    unsigned long red   = 0xff * 0x10000;
    unsigned long green = 0xff * 0x100;
    unsigned long blue  = 0xff;
    unsigned long color = red + green + blue;

    cout << hex << red   << "\n";
    cout << hex << green << "\n";
    cout << hex << blue  << "\n";
    cout << hex << color << "\n";
}

这是有道理的。但是,我尝试在我的Arduino上运行以下命令:

ff0000
ff00
ff
ffffff

除非我遗漏了某些内容(完全可能),否则此代码在功能上是相同的,除非它使用不同的方法来编写其输出。但是,这就是打印出来的内容:

void setup(){
    unsigned long red   = 0xff * 0x10000;
    unsigned long green = 0xff * 0x100;
    unsigned long blue  = 0xff;
    unsigned long color = red + green + blue;

    Serial.begin(9600);
    Serial.println(String(red,   HEX));
    Serial.println(String(green, HEX));
    Serial.println(String(blue,  HEX));
    Serial.println(String(color, HEX));
}

void loop(){}

怀疑架构可能与它有关,我尝试在Mega 2560和Rainbowduino 3.0(基本上是一个Duemilanove w / ATmega 328)上运行该代码,两者都有相同的结果。如果我使用不同的数据类型,例如ff0000 ffffff00 ff feffff

,我也会得到相同的结果

我真的不知道发生了什么。有人可以提供解释吗?

1 个答案:

答案 0 :(得分:2)

在C ++中,常量表达式在编译时计算。看起来arduino的编译器已经错误地执行了计算 - 它将0xFF视为否定,并对其进行了符号扩展;这就是为什么顶部字节设置为0xFF

您可以使用type-specific suffixes强制常量使用正确的类型,如下所示:

unsigned long red = 0xffUL * 0x10000UL;
unsigned long green = 0xffUL * 0x100UL;
unsigned long blue = 0xffUL;
unsigned long color = red + green + blue;

UL后缀代表unsigned long

不是将数字乘以2的幂并将结果相加,您可以使用shift和按位OR,如下所示:

unsigned long red = 0xffUL;
unsigned long green = 0xffUL;
unsigned long blue = 0xffUL;
unsigned long color = (red << 16)
                    | (green << 8)
                    | (blue << 0);

上面的零位移是完全没必要的 - 编译器会优化它。我添加了它以获得更一致的外观。