作者tropical72 (藍影)
看板C_and_CPP
標題Re: [問題] 32bit機器上輸入12 digits數字
時間Mon Jun 18 18:28:47 2012
引述
: 讓使用者輸入的是10進位的數,最大到999,999,999,999。
: 原來提供輸入的函式是存成char array,所以會變成
: addr 0x39
: addr+1 0x39
: ...
: addr+11 0x39 (共12 Bytes) 這也是我說的包袱的部分....沒法改
: 最後要輸出給另外一個I/O的必須變成 0xE8D4A50FFF (999,999,999,999的16進位)
: addr 0xFF
: addr+1 0x0F
: addr+2 0xA5
: addr+3 0xD4
: addr+4 0xE8
我提個細節你參考一下好了。為說明方便,這裡只使用 4 bytes ascii, "1123" ,
並假設是要存到 unsigned char big[2] 裡面去。
< 你的問題可以順利轉換從 12 bytes 存到 unsigned big[2] 裡去 >
一開始你可以先從 0x31 0x31 0x32 0x33 轉成 0x01 0x01 0x02 0x03
const size_t size= 4;
char str[4] = "1123";
for(i=0; i< size; ++i) str[i] - '0';
上面步驟實際上可省下來和其它步驟一起做,但因為比較複雜就不這麼做了。
再來是重點,從 10 進位轉成 2 進位。
圖畫得很醜,是連除法的示意圖,湊合著看。
< 第零次 >
2 | 1 1 2 3 --> 初始化 : 商=0, 餘=0, R=0
-------------
2 | 0 --> (0) : 被除=str[0]+R=0, 除=2 > 商=0,餘=1,R=餘*10=10
-------------
str[0] = 商 = 0 ( 最後 assigned)
2 | 0 5 --> (1) : 被除=str[1]+R=11,除=2 > 商=5,餘=1,R=餘*10=10
-------------
str[1] = 商 = 5
2 | 0 5 6 --> (2) : 被除=str[2]+R=12,除=2 > 商=6,餘=0,R=餘*10= 0
-------------
str[2] = 商 = 6
2 | 0 5 6 1 --> (3) : 被除=str[3]+R=3 ,除=2 > 商=1,
餘=1,R=餘*10= 10
-------------
str[3] = 商 = 1
最後的餘 1,放到 big[0]:bit0 , bit[0] = 0000 0001 = 0x01
< 第壹次 >
2 | 0 5 6 1 --> 初始化 : 商=0, 餘=0, R=0
-------------
2 | 0 --> (0) : 被除=str[0]+R=0, 除=2 > 商=0,餘=0,R=餘*10=0
-------------
str[0] = 商 = 0
2 | 0 2 --> (1) : 被除=str[1]+R=5, 除=2 > 商=2,餘=1,R=餘*10=10
-------------
str[1] = 商 = 2
2 | 0 2 8 --> (2) : 被除=str[2]+R=16,除=2 > 商=8,餘=0,R=餘*10= 0
-------------
str[2] = 商 = 8
2 | 0 2 8 1 --> (3) : 被除=str[3]+R=1 ,除=2 > 商=0,
餘=1,R=餘*10= 10
-------------
str[3] = 商 = 1
最後的餘 1,放到 big[0] : bit1 , bit[0] = 0000 0011 = 0x03
<.... 中間略過 ... >
< 第柒次 >
2 | 0 0 0 4 --> 初始化 : 商=0, 餘=0, R=0
-------------
2 | 0 --> (0) : 被除=str[0]+R=0, 除=2 > 商=0,餘=0,R=餘*10=0
-------------
2 | 0 0 --> (1) : 被除=str[1]+R=0, 除=2 > 商=0,餘=0,R=餘*10=0
-------------
2 | 0 0 0 --> (2) : 被除=str[2]+R=0, 除=2 > 商=0,餘=0,R=餘*10=0
-------------
2 | 0 0 0 2 --> (3) : 被除=str[3]+R=4 ,除=2 > 商=2,
餘=0,R=餘*10=10
-------------
到第七次的時候(從第0次算起),big[0] = 0110 0011 = 0x63,
已算滿了 sizeof(unsigned char) * CHAR_BIT = 8 次,
所以再來就是往 big[1]: bit 0 重新開始了。
照著以上的步驟跑,最後可以算出
"1123" = (0000 0100) (0110 0011) = 0x04 0x63
那到底要計算到
第 x 次 ?二種方式。
(1) 直接計算 ceil ( n * log2(x) ) ,不過一般不用這個做停止條件。
(2) 當計算過程中, 只要商全部為零就是停止條件了。
< 怕數學不好出錯的話,就是商全為零、餘也為零>
事實上要從 asscii 轉到 2 進位不像轉到 10 進位那麼容易,
可能也有點花時間,以 n bytes ascii array 而言,
複雜度應是 O(nlogn)。
怎麼轉到你的問題,相信你已有了想法。
這沒用到什麼神奇的演算法,只是把思緒細節拆出來而已,一點意見,供參考。
--
我知道 ~ 但別說出來 ,
說出來讓人感到特別難過...
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.76.161
→ tropical72:Orz 用錯帳號了.. 06/18 18:30
推 s3748679:0.0" 06/18 21:47
推 purincess:一樓XDDD 06/18 23:24
推 ericinttu:我比較習慣這個ID啊 XD 06/19 03:24
推 VictorTom:1F露餡了XD 06/19 09:00
推 WillyLin:瞭解了...感謝!!!!! 06/19 09:04
→ hilorrk:原來是同一個人XDD 06/19 14:06
→ loveme00835:( ′-`)y-~ 我應該是第一個看穿的 06/19 14:30
推 LPH66:記得幾天前好像也自爆過一次的樣子 XD? 06/19 18:35
→ tropical72:是啊,其實不會怕別人知道,真的只是要查之前文章不好查, 06/19 18:47
→ tropical72:再加上 EdisonX 是網路上用較多的,也不怕別人聯想。 06/19 18:48
推 WillyLin:我去過上面EdisonX大大的網頁了...後悔今天才看見神!!! 06/19 23:57
→ tropical72:不不不,我很嫩,只是版上高人沒時間回覆而已。 06/20 00:43
→ james732:這個板越強的人越會說嫩,樓上跟板主是最好的代表XDDD 06/20 00:44
→ s3748679:排除厲不厲害,很用心很投入是真的。 06/20 01:08
→ james732:真的,超用心的 06/20 01:09
→ hilorrk:樓上可是不惶多讓~都是我學習的對象啊 06/20 01:17
→ james732:樓上這麼說我一點都不會開心的 (扭) 06/20 01:18
→ angleevil:樓上是我學習的對象,版主和EdisonX也是<(__)> 06/21 19:28
→ purincess:EdisonX和tropical72也是<(__)> 阿不對 是同一個人XD 06/24 23:01
→ hilorrk:樓上婊很大XDD 06/25 01:40
→ EdisonX:樓上 p 大、h 大 有梗 :) 06/25 04:00