N進位制漫談
轉自:http://zhidao.baidu.com/s/daily/2014-03-19/1398947138.html#pn=1
導語:幾個有趣的N進位制小遊戲,您準備好了嗎?卡片魔術背後的數學、數學家抓程式設計bug、有限區間內實數數目不可數的巧妙證明,本文作者將告訴您,N進位制又好玩又有用!
作者:科學公園 驚鶴聞風(南京大學數學系副教授)
【一個傳統小遊戲】
設計四張卡片:
第一張寫有 1, 3, 5, 7, 9,11,13,15
第二張寫有 2, 3, 6, 7,10,11,14,15
第三張寫有 4, 5, 6, 7,12,13,14,15
第四張寫有 8, 9,10,11,12,13,14,15
某甲心裡想一個0-15間的整數,告訴你此數共在哪些卡片裡有。你將這些卡片的第一個數加起來,就得到某甲心裡想的那個數。
這個遊戲很多人見過,但未必都知道其背後的數學道理就是二進位制。解釋如下:
第一張卡片中是0-15間所有二進位制表示為xxx1的數,而其第一個數是0001。第二張卡片中是0-15間所有二進位制表示為xx1x的數,而其第一個數是0010。後兩張類推。
例如,某甲心裡想的數是13,這個數的二進位制表示是1101,因此它在第一、三、四張卡片裡有,而且正等於0001 + 0100 + 1000。
【幾個IT相關的二進位制問題】
1.在美國的公司剛剛工作不久的一天,一位計算機專業的小夥子跑來找我,說他新裝的VB6是有BUG的,讓我看看。他的即時視窗裡顯示: 3.0 – 2.99 = 0.00999999999999979。
我告訴他有一個檔案叫IEEE754,可以解惑,他堅持讓我說。於是我告訴他:double 數型有64個二進位制位,其中第1位是表示正負符號的,第2至12位是表示帶偏移的指數的,後52位是表示“小數”的。2.99無法用二進位制精確表示,所以才造成他看到的結果。這是 double 與生俱來的,不是VB6的BUG。
2.不久,公司一位波蘭女孩找我,說公司讓她編的“四捨五入”函式會出現工作異常。
我看了程式碼,發現她所寫的round( r, n ) 函式,基本上等於是 floor( r*10^n + 0.5 ) / 10^n。這程式碼裡也有double之二進位制儲存產生的問題。
例如,round(1.005, 2)=1.01。但是,1.005不能用double精確表示,它的表示約為1.0049999999999998。因此,以上程式碼計算的“r*10^2 + 0.5”約等於100.999999999998,取整後為100。結果,其程式碼給出的答案是1.00,錯了。
3.在做偏微分方程的迭代求解時,我發現迭代N次後的結果在debug模式與release模式下不一致。仔細分析程式碼,發現類似1.0 + 0.25*DBL_EPSILON + 0.25*DBL_EPSILON 的計算式,在兩種模式之下的計算結果分別為1.0與1.0+DBL_EPSILON。原因在於後一種模式預設某種“優化”計算……不細說。
還有其他問題,很多都牽涉到double在計算機內部的二進位制表示。瞭解IEE754的規定,才能夠找到問題所在以及解決辦法。這個知識點對IT高手不是問題,但相對入門級的新手很有用。
【用三進位制證明( 0, 1 )中的實數不可數】
首先,把( 0, 1 )中的實數用三進製表示;其次,用反證法,假設( 0, 1 )中的實數是可數個。
由於是可數個數,因此可以將所有這些數寫成數列x(n)。
構造一個三進位制小數y:其第一位小數取數與x(1)的第一位不同,且不取2;從第二位小數開始,第n位取不同於x(n)的第n位,且與y已經取得的前一位不同——例如,設x(10)為2,y 的第9位已經取0,則y 的第10位取1。
不難證明,此y是( 0, 1 )中的實數,且不等於數列x(n)中的任何一個。也就是說,數列x(n)不可能包括全部( 0, 1 )中的實數。
這證明,( 0, 1 )中的實數是不可數個,也就是說:不可能把( 0, 1 )中的實數一一對應到自然數集上。
【康威十三進位制數】
文不對題一下,我們只考慮使用十一進位制,康威十三進位制數留給好奇者去探索。
用A記10,用十一進製表示所有( 0, 1 )中的實數。
在所有這些十一進製表示的( 0, 1 )中的實數裡,考慮A僅出現有限次的那些數。對一個這種數x,去掉其最後出現的A之前的所有數字,把A改成“0.”,則得到一個新的小數y。把y解讀為十進位制小數,則我們構造了一個從( 0, 1 )到( 0, 1 )的對映。
關鍵是,這個對映中,( 0, 1 )內的每一個數都有無窮多個原像。也就是說( 0, 1 )可以映滿( 0, 1 )無窮多次。
其實,( 0, 1 )可以映滿( 0, 1 ) * ( 0, 1 )。證明怎麼構造,這裡先不說了……
總之,N進位制可以很好玩,可以很有用……
相關文章
- n進位制轉十進位制
- lua之m進位制轉換為n進位制-任意進位制轉換演算法演算法
- 進位制詳解:二進位制、八進位制和十六進位制
- .C++整數的N進位制字串表示C++字串
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- JavaScript 二進位制、八進位制與十六進位制JavaScript
- JavaScript 進位制轉換(2進位制、8進位制、10進位制、16進位制之間的轉換)JavaScript
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- Python 進位制互相轉換(二進位制、十進位制和十六進位制)Python
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- N位二進位制數加減法運算圖靈機圖靈
- Qt進位制轉換(十進位制轉十六進位制)QT
- 1474 十進位制轉m進位制+1475 m進位制轉十進位制
- [計算機基礎] 計算機進位制轉換:二進位制、八進位制、十進位制、十六進位制計算機
- C# 2進位制、8進位制、10進位制、16進位制...各種進位制間的輕鬆轉換C#
- 十進位制轉十六進位制
- 10進位制 VS 2進位制
- 二進位制、十進位制與十六進位制相互轉化
- 大話二進位制,八進位制,十進位制,十六進位制之間的轉換
- 一看就懂二進位制、八進位制、十六進位制數轉換十進位制
- python進位制轉換(二進位制、十進位制和十六進位制)及注意事項Python
- Oracle中的二進位制、八進位制、十進位制、十六進位制相互轉換函式Oracle函式
- 進位制之間的轉換之“十六進位制 轉 十進位制 轉 二進位制 方案”
- 十進位制——二 (八、十六 )進位制
- 45:十進位制到八進位制
- 46:八進位制到十進位制
- 十六進位制數轉十進位制
- 進位制
- C語言十進位制,八進位制,十六進位制輸出分析C語言
- 【進位制轉換】十進位制與十六進位制相互轉換方法
- 【轉帖】Oracle中的二進位制、八進位制、十進位制、十六進位制相互轉換函式Oracle函式
- 二進位制轉十進位制快速方法
- 二進位制與二進位制運算
- 十六進位制轉換為八進位制
- 十六進位制轉換為十進位制