2015-11-01 4 views
2

Учитывая целое число без знака, мне нужно получить шестнадцатеричное шестнадцатеричное значение длиной 6 цифр.C++ trim и pad unsigned int в шестнадцатеричном значении для #RGB

  • 81892 (Hex: 13FE4), должны стать 13FE40 или 013FE4
  • 3285446057 (гекс: C3D3EDA9), должны стать C3D3ED или D3EDA9

Так как проект я вношу свой вклад в использование Qt, я решаю проблему следующим образом:

unsigned int hex = qHash(name); 
QString hexStr = (QString::number(hex, 16) + "000000").left(6); 
bool ok; 
unsigned int hexPat = hexStr.toUInt(&ok, 16); 

Это прокладывает шестнадцатеричную строку справа, а затем обрезает ее после шестого символа слева. Для того, чтобы сделать наоборот, я бы просто заменить вторую строку:

QString hexStr = ("000000" + QString::number(hex, 16)).right(6); 

Значение будет used for RGB values, поэтому мне нужно шесть шестнадцатеричных цифр (три значения от 0 до 255).

Есть ли более эффективный способ достижения (или обоих) этих результатов без преобразования в строку, а затем обратно?

ответ

2

Настоящим требованием для вашей проблемы является с учетом целых чисел без знака, вам нужно извлечь три байта.

На самом деле нет необходимости конвертировать в строку для их извлечения, ее можно более эффективно выполнять с помощью бит-операций.

Чтобы извлечь любые байты из целого числа, сдвиг вправо (>>) соответствующее число бит (0, 8, 16 или 24), а AND результата с маской, которая принимает только крайние правые байты (0xFF, который действительно 0x000000FF).

например. взять три младшие байты:

uint c = hash(...); 
BYTE r = (BYTE)((c >> 16) & 0xFF); 
BYTE g = (BYTE)((c >> 8) & 0xFF); 
BYTE b = (BYTE)(c & 0xFF); 

или три наиболее значимые байты:

uint c = hash(...); 
BYTE r = (BYTE)((c >> 24) & 0xFF); 
BYTE g = (BYTE)((c >> 16) & 0xFF); 
BYTE b = (BYTE)((c >> 8) & 0xFF); 
+0

BYTE как в http://stackoverflow.com/a/20025042/188159? Могу ли я использовать int или unsigned int вместо этого, чтобы не включать что-либо и определять новые типы? (Я чувствую, что должен это делать, поскольку я почти не знаю проект, в который я вношу свой вклад, и, вероятно, пока не знаю, какие последствия могут иметь такие дополнения к производительности и другим разделам кода). PS: Спасибо за повторное утверждение моего вопроса, это очень полезно для понимания процесса. – qubodup

+0

Извините, я привык к Windows, я забыл, что это не язык. 'BYTE' определяется как' unsigned char'. Возможно, он работает так же хорошо, хотя и менее конкретный, с int или uint, зависит от того, где значения должны идти позже. – Rotem

+0

Спасибо за разъяснение. Я особенно заинтересован в использовании самых значительных байтов (левая часть), но, к сожалению, ваш код, похоже, не обрабатывает короткие хэши. 1cf9e становится 00,01, cf вместо 1c, f9, e0 и ef становится 00,00,00, а не ef, 00,00 http://rextester.com/PGV72502 (также случается при использовании unsigned char, а не без знака int) - Я также обеспокоен тем, что это может быть непоследовательно между 32-битными/64-битными операционными системами? – qubodup