2014-04-15 2 views
1

저는 오랫동안 높은 수준의 동적 유형 언어로 코딩했지만 최근에는 C++ (Arduinos에서)로 작업하기 시작했습니다. 저는 까지 올라갈 하나의 unsigned long00xFF (RGB 색상 값) 사이의 3을 int으로 변환하는 함수를 작성하려고합니다. 부호없는 long은 0xFFFFFFFF까지 올라갈 수 있습니다.Arduino의 16 진수 곱셈

나는 내 개인 컴퓨터에서 다음 테스트를 쓰고 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"; 
} 

출력은 예상대로 :

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(){} 

을 나는 (완전 수) 뭔가를 누락하지 않는 한 그것의 출력을 쓸 수있는 다른 방법을 사용하는 것을 제외하고,이 코드는 기능적으로 동일하다. 그러나,이 그것을 밖으로 인쇄 것입니다 : 해당 아키텍처 의심

ff0000 
ffffff00 
ff 
feffff 

함께 할 수있는 뭔가가있을 수 있습니다, 나는 메가 2560 기본적으로 ATMEGA 328 승/Duemilanove 인 Rainbowduino 3.0 (에 그 코드를 실행 시도) 둘 모두에 동일한 결과가 나타납니다. uint32_t과 같은 다른 데이터 유형을 사용하면 동일한 결과를 얻습니다.

나는 실제로 무슨 일이 일어나는지 전혀 모른다. 누구든지 설명을 해줄 수 있습니까?

답변

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을 의미합니다.

오히려 둘의 힘에 의해 수를 곱한 다음과 같이 결과까지, 당신은 변화와 비트를 사용할 수있는 추가 또는보다 : 위의

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

제로 전환이 완전히 불필요 - 컴파일러는 그것을 밖으로 최적화합니다. 좀 더 일관된 모양으로 추가했습니다.

+0

두 가지 솔루션 모두 완벽하게 작동합니다. 좋은 설명 주셔서 감사합니다! –