現有一需求,計算拷貝文件的進度。假設已知文件總大小t字節,已拷貝了n字節。
對於如此簡單的需求,大多數人會第一時間這樣實現
- int progress(int t, int n)
- {
- //已完成除以總大小
- return n/t*100;
- }
很抱歉,這樣實現你將發現它會只有兩個值——0和100。原因是,當一個整數除以另一整數,如果小於0,則 向下取整爲0,0*100自然也是等於0。
有人於是用以下實現
- int progress(int t, int n)
- {
- return 100*n/t;
- }
這種方式在多數情況下工作比較理想,直到某一天,你遇到一個大於2G的文件,你發現傳統的32位整數表示不了了。 於是採用64位
- int progress(off_t t, off_t n)
- {
- return 100*n/t;
- }
off_t是個不錯的寫法,它在不同系統上有不同的定義。可是,你又發現有人給你傳了一個大於文件總大小的值,計算的值超過100了!再改改
- int progress(int t, int n)
- {
- return min(100*n/t, 100);
- }
不過既然有特殊情況,萬一傳過來是負的怎麼辦?再判斷一下咯
- int progress(int t, int n)
- {
- if (t < 0 || n < 0)
- return 0;
- return min(100*n/t, 100);
- }
應該沒問題了吧。但是,你可能沒料到,一個足夠大的文件,即使64位下,100*n也可能溢出!TMD,真的要逼我祭出絕殺武器嗎
- int progress(int t, int n)
- {
- if (t < 0 || n < 0)
- return 0;
- double p = double(n);
- p /= t;
- p *= 100;
- return min(int(p), 100);
- }
應該行了吧,老子都用到雙精度了。
呃……最後一句int(p)是個隱患,尼瑪能保證p不超過64位整形?
- int progress(int t, int n)
- {
- if (t < 0 || n < 0)
- return 0;
- double p = double(n);
- p /= t;
- p *= 100;
- if (p > 99.0)
- return 100;
- else
- return int(p);
- }
相安無事了很長時間,直到一天,一個腦殘的傢伙給了一個大小爲0的文件
程序員真的是一件很危險的職業……
作者:annidy
版權所有,轉載請註明出處 blog.csdn.net/ani_di