今天我只是在玩基本轉換從一個基地到另一個。我注意到一些代碼從十六進制轉換爲八進制,我注意到它大多使用中間轉換爲十進制或二進制,然後回到八進制。它可以寫我自己的函數來將十六進制字符串轉換爲八進制字符串,而不使用任何中間轉換。我也不想使用內置printf
選項,如%x
或%o
。感謝您的投入。十六進制到八進制的轉換程序不使用十進制或二進制
回答
當然這是可能的。一個數字是一個數字,不管它是什麼數字系統。唯一的問題是人們習慣於十進制,這就是爲什麼他們更好地理解它。您可以從任何基地轉換爲其他基地。
編輯:關於如何執行轉換的更多信息。
首先注意3個十六進制數字映射到正好4個八進制數字。因此,有十六進制數字的號碼你可以很容易找到的八進制數字的位數:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int get_val(char hex_digit) {
if (hex_digit >= '0' && hex_digit <= '9') {
return hex_digit - '0';
} else {
return hex_digit - 'A' + 10;
}
}
void convert_to_oct(const char* hex, char** res) {
int hex_len = strlen(hex);
int oct_len = (hex_len/3) * 4;
int i;
// One hex digit left that is 4 bits or 2 oct digits.
if (hex_len%3 == 1) {
oct_len += 2;
} else if (hex_len%3 == 2) { // 2 hex digits map to 3 oct digits
oct_len += 3;
}
(*res) = malloc((oct_len+1) * sizeof(char));
(*res)[oct_len] = 0; // don't forget the terminating char.
int oct_index = oct_len - 1; // position we are changing in the oct representation.
for (i = hex_len - 1; i - 3 >= 0; i -= 3) {
(*res)[oct_index] = get_val(hex[i]) % 8 + '0';
(*res)[oct_index - 1] = (get_val(hex[i])/8+ (get_val(hex[i-1])%4) * 2) + '0';
(*res)[oct_index - 2] = get_val(hex[i-1])/4 + (get_val(hex[i-2])%2)*4 + '0';
(*res)[oct_index - 3] = get_val(hex[i-2])/2 + '0';
oct_index -= 4;
}
// if hex_len is not divisible by 4 we have to take care of the extra digits:
if (hex_len%3 == 1) {
(*res)[oct_index] = get_val(hex[0])%8 + '0';
(*res)[oct_index - 1] = get_val(hex[0])/8 + '0';
} else if (hex_len%3 == 2) {
(*res)[oct_index] = get_val(hex[1])%8 + '0';
(*res)[oct_index - 1] = get_val(hex[1])/8 + (get_val(hex[0])%4)*4 + '0';
(*res)[oct_index - 2] = get_val(hex[0])/4 + '0';
}
}
而且這裏是ideone讓你可以用它玩的例子:example。
可否請您詳細說明一些支持代碼段。謝謝 – CppLearner
您期望什麼輸入和輸出?字符數組? –
是的,字符數組字符串的十六進制和字符數組字符串作爲八進制輸出 – CppLearner
是的,你可以做得相對容易:四個八進制數字總是轉換爲三個十六進制數字,所以你可以將你的字符串拆分成三個十六進制數字的組,並且從後面處理每個組。如果您沒有足夠的十六進制數字來完成一組三個數字,請添加前導零。
每個十六進制數字給你四位;拿最後三個,並將它們轉換爲八進制。添加接下來的四個,然後再增加三個八進制位。添加最後一組四個 - 現在總共有六位,所以將它們轉換爲兩個八進制數字。
這樣可以避免將整個數字轉換爲二進制數,儘管在轉換數字的過程中會使用「滑動」二進制窗口。
考慮一個例子:將62ABC
轉換爲八進制。劃分爲三個數字組:062
和ABC
(注意在62
前面添加的零爲3個數字組)。
開始從後面:
C
,或1100
,被切成1
和100
,使得八4
,併爲下一步B
,或1011
1
額外的位,被剁成10
用於下一步,11
用於此步驟。所述1
來自前一步驟附接在的11
右側,使得一個八進制7
A
,或1010
,被切碎成101
和0
。上一步的10
附在右側,使得010
或八進制2
。101
是八進制5
,所以我們有5274
到目前爲止。2
變爲2
和0
用於下一步;6
變成4
和01
用於下一步;0
變成0
和1
(因爲01
從上一步中被添加)。
最終結果是01425274
。
謝謝我不符合你的速度。例如5274八進制轉換爲十六進制的ABC。請你詳細說明如何達成解決方案。 – CppLearner
@CppLearner看看這個例子。 – dasblinkenlight
謝謝@dasblinkenlight,但我想要避免這種中間二進制轉換。 – CppLearner
計算機內存中的所有數字都是以2爲底的。因此,無論何時您想要使用數值操作(數學運算),您都需要將它們作爲整數,浮點數等。因此,它非常方便,未來通過可計算類型進行轉換。
我會避免直接字符串到字符串轉換,除非值可能太大,以適應數字變量。從頭開始編寫可靠的轉換器是非常困難的。
(使用基地10使得二進制計算機很沒有意義。)
這是一個有點棘手,因爲你會被轉換的4位組的3位組 - 你可能會想用12工作位,即3個十六進制數字到4個八進制數字,然後你必須分別處理剩餘的位。
E.g.到5274八進制轉換爲十六進制:
5 2 7 4
101 010 111 100
|||/ \\// \|||
1010 1011 1100
A B C
Thanks @Paul R,但在這種情況下,我們不是將它轉換爲二進制和中間步驟。 – CppLearner
你有一個小的滑動二進制窗口,是的 - 我沒有看到任何替代方案,因爲你需要重新組合這些位。 –
似乎是一個非常簡單的任務交給我,你想要一個十六進制字符串,並且希望將其轉換爲一個八進制的字符串。讓我們以ASCII十六進制,並將其轉換爲int類型一起工作:
char hex_value[] = "0x123";
int value = strtol(hex_value,NULL,16);
它仍然是十六進制在這一點上,那麼如果我們想從一個基站轉換到另一個有簡單的數學可以做:
123/8 = 24 R 3
24/8 = 4 R 4
4/8 = 0 R 4
這就告訴我們,123 == 443 所以我們要做的就是寫數學爲基本功能,並把最終值回字符串:
char * convert_to_oct(int hex)
{
int ret = 0, quotient = 0, reminder = 0, dividend = hex, counter = 0, i;
char * ret_str; // returned string
while(dividend > 0){ // while we have something to divide
quotient = dividend/0x8; // get the quotient
reminder = dividend - quotient * 0x8; // get the reminder
ret += reminder * pow(10, counter); // add the reminder (shifted)
// into our return value
counter++; // increment our shift
dividend = quotient; // get ready for the next divide operation
}
ret_str = malloc(counter); // allocate the right number of characters
sprintf(ret_str, "%d", ret); // store the result
return ret_str;
}
所以這個函數會將一個十六進制(int)值轉換成一個八進制字符串。你可以把它想:
int main()
{
char hex_value[] = "0x123";
char * oct_value;
int value = strtol(hex_value,NULL,16);
// sanity check, see what the value should be before the convert
printf("value is %x, auto convert via printf gives %o\n", value, value);
oct_value = convert_to_oct(value);
printf("value is %s\n", oct_value);
謝謝@Mike。我喜歡你的方法。但我認爲這是在從十二月到八月的轉變。執行此int值後的原因值= strtol(hex_value,NULL,16);值將包含十進制值。convert_to_oct邏輯將爲十進制到十進制。 – CppLearner
@CppLearner - 完全沒有。 'strtol'函數中的'16'將值保存爲一個十六進制數。如果您在'strol'之後立即將此值作爲十進制'printf(「%d」,value)「輸出,您將看到顯示值爲291(123hex == 291dec)。這裏唯一的轉換是從一個十六進制值的ASCII表示到一個整數十六進制值。 – Mike
@CppLearner - 現在,如果你不想轉換爲整數**這是一個不同的故事......但我沒有看到你的原始文章中的要求。 – Mike
- 1. 二進制,八進制,十六進制到十進制程序
- 2. 從十六進制到十進制,二進制到十進制和八進制到十進制程序C++
- 3. 十六進制,八進制,二進制到十進制(C++)
- 4. 將十六進制轉換爲二進制到十六進制?
- 5. 將十進制轉換爲二進制,八進制和十六進制?
- 6. 將十進制數轉換爲二進制/十六進制/八進制符號
- 7. 轉換十六進制,十進制,八進制和ASCII?
- 8. 將八進制數轉換爲十進制和十六進制
- 9. 轉換爲八進制,二進制和十六進制在JavaScript
- 10. 十六進制到二進制轉換
- 11. 轉換十六進制到二進制
- 12. 二進制到十六進制轉換
- 13. C#System.OverflowException二進制到十進制和十六進制轉換
- 14. 轉換十六進制到十進制
- 15. 將十進制轉換爲十六進制和十六進制
- 16. 將二進制十進制轉換爲十六進制,二進制和八進制字符串
- 17. 將十進制轉換爲十六進制/二進制
- 18. 十進制/十六進制/二進制轉換
- 19. 十六進制轉換爲二進制
- 20. 十六進制轉換爲二進制
- 21. 十六進制和十進制轉換
- 22. 使用十進制或十六進制
- 23. 十六進制,二進制和八進制到十進制轉換器不能正常工作C++
- 24. 十六進制到十二進制轉換(帶sed的管道)
- 25. C++將二進制轉換爲十進制,八進制
- 26. PHP - 轉換八進制/十六進制轉義序列
- 27. 二進制到十進制和十進制到二進制轉換器
- 28. 浮點十六進制八進制二進制
- 29. 如何十六進制或十進制轉換爲二進制目標C
- 30. 二進制轉換爲十六進制和十六進制轉換爲二進制
http://www.physicsforums.com/showthread.php?t=40575 – 2013-01-10 15:16:57
這是一個有點棘手,因爲你會被轉換的4位組的3位組 - 你可能要一次處理12位數據,即3個十六進制數字到4個八進制數字,然後您必須分別處理剩餘的位。 –
謝謝@保羅R,我仍不滿足你的速度。如果你能詳細說明會有幫助。 – CppLearner