我正在研究Cortex M0 cpu,它沒有硬件劃分,所以每次我劃分一些內容時,都會使用GCC庫函數。現在我所做的最多的一個分割是256,將短路轉換爲字節。有什麼辦法可以更有效地實現(比如通過位移),比默認的GCC庫能做到嗎?高效地將16位短轉換爲8位字符
回答
根據你的意見,你要-32768映射到0,32767映射到255因此,你想計算公式爲:
short s = /* input value */;
unsigned char c = (unsigned char) ((s + 32768)/256);
其他評論者所指出的,你可以做到這一點除以256右移或其他各種戰術,這是真的 - 這個合理的版本是:
unsigned char c = (unsigned char) ((s + 32768) >> 8);
但是,不需要這種優化。 GCC是有關轉換除以恆定操作成特殊情況的實現很聰明,在這種情況下它編譯這兩種成完全相同的代碼(具有-O2 -mcpu=cortex-m0 -mthumb
和GCC 4.7.2測試):
mov r3, #128
lsl r3, r3, #8
add r0, r0, r3
lsr r0, r0, #8
uxtb r0, r0
如果你試圖太聰明(如同其他答案中的聯合或指針示例一樣),你可能會混淆它,並使事情變得更糟 - 特別是因爲那些工作是通過內存加載的,並且添加32768意味着你已經擁有了寄存器中的值。
你一定會感到驚訝......我曾經看到過一個GCC端口,它通過發出乘法操作碼來處理C代碼中的顯式移位操作 - 有人可能假定了一個硬件乘法器,因此等價於成本,儘管它嘗試的實際實驗硬件運行沒有執行的乘法指令。幸運的是,作爲一個FPGA,很容易添加。希望分案的情況能夠得到更好的處理。 –
@ChrisStratton:是的 - 這就是爲什麼每隔一段時間閱讀一次生成的程序集很有用,只是爲了確保你的想法正在發生實際上正在發生!雖然你描述的情況很明顯是GCC中的一個錯誤。 –
只是投了一個指針。
unsigned char *bytes = (unsigned char*)&yourvalue;
現在,bytes[0]
會捏捏你的價值的一個字節,並bytes[1]
將舉行日等。 順序取決於你的系統的字節序
請問downvoter請詳細說明一下嗎? –
@JanDvorak是的,但答案**指出**結果取決於字節順序。所以它絕不是不正確的。另外,OP知道他正在開發哪種架構,所以他事先知道排序。 –
當獨立於平臺的代碼更乾淨並且可能更快時,編寫平臺相關代碼幾乎沒有什麼理由 - 程序不一定將其整個生命週期花在它們最初編寫的目標上。在移位情況下,變量可能被優化編譯器保存在寄存器(而不是內存)中的可能性相當高;在指針情況下,可能會有一些優化編譯器足夠聰明地發現這是您使用指針並使用寄存器實現的唯一原因,但似乎不太可能。 –
你可以使用union
這樣:
#include <stdio.h>
union Word {
struct {
unsigned char high;
unsigned char low;
} byte;
unsigned short word;
};
int main(int argc, char **argv) {
union Word word;
word.word = 0x1122;
printf("L = 0x%x, H = 0x%x", word.byte.low, word.byte.high);
return 0;
}
使用union和bit-shifting會有性能提升嗎?看起來工會會更快,因爲沒有必要的額外操作,但也許還有其他開銷? – Muis
@Joshua在彙編級別,使用'union'只有'mov'指令。 – 2013-02-03 17:20:45
**這會給出錯誤的答案**,因爲它假設一個Big-Endian處理器,但是所討論的目標實際上是Little-Endian。你可以修復它,但仍然存在錯誤的風險,特別是如果代碼被移植到別的地方。 –
- 1. DICOM將16位轉換爲8位
- 2. QT轉換16位QImage爲8位無符號字符在QT
- 3. 8位到16位轉換
- 4. 使用numpy高效地將16位圖像數據轉換爲8位顯示,並進行強度縮放
- 5. 8位至16位ALU轉換
- 6. 轉換16位PCM到8位
- 7. 需要將16位數據轉換爲8位
- 8. 將16位整數轉換爲8位整數?
- 9. 將RGB圖像轉換爲RGB 16位和8位
- 10. 如何將VHDL中的8位轉換爲16位?
- 11. 將16位深度CvMat *轉換爲8位深度
- 12. OMRON將16位數字轉換爲ASCII
- 13. 將24位bmp轉換爲16位?
- 14. 將16位轉換爲32位浮點
- 15. Python將32位轉換爲16位tiff
- 16. 如何將8位字節轉換爲6位字符?
- 17. 將8位無符號PCM轉換爲8位帶符號PCM
- 18. 將16位帶符號的PCM轉換爲帶有符號的16位
- 19. 將無符號16位int轉換爲C#中有符號16位int int#
- 20. Java位移位,短轉換爲字節
- 21. 的16位字節的最高位轉換爲符號整型在Python
- 22. 將UIImage轉換爲8位
- 23. 轉換8位SSE寄存器,以16個短褲
- 24. 將8位int轉換爲32位
- 25. 將32位實數轉換爲2x 16位字節
- 26. 轉換8 16位SSE寄存器8位數據
- 27. 將字符轉換爲16位的unicode編碼
- 28. 將表示16位的字符串轉換爲int c#
- 29. 如何將兩個16位整數(高位字/低位字)轉換爲32位浮點數?
- 30. 將UTF-16和UTF-8文本字符串轉換爲UTF-8
運營商'>>'會爲你做詭計嗎?你知道'8'嗎? –
難道你不是指用256除?不是255? –
你可能會對Hacker's delight這本書的第10章,Integer除以常量感興趣。但GCC實施者可能已經閱讀過它。假設有更好的方法之前,你有沒有看過裝配體? (注意:這個評論假定你**的**意味着255) –