2038年1月19日3時14分7秒

人類和計算機有很大的不同,人腦擁有超強的事物辨析能力、決策處理能力和自我學習能力,並以此彌補了存儲(記憶)上的不足;而電腦計算和邏輯處理的基礎都極為簡單,簡單到只會1+1、與或非,簡單到連10進位都嫌麻煩,但它速度超快、容量超大、記憶力超好,所以在很多規則性強的領域幾乎無人能敵。

舉個例子,人類使用的計時系統就很複雜,又是年月日,又是時分秒,一會兒12進位,一會兒60進位,偶爾還來個28、29、30、31不等(月份天數)的進位。如果計算機也這麼搞,它顯然不樂意,像前面說的它連10進位都嫌麻煩。Unix系統採用了一種超級簡單粗暴的方式:以Unix誕生之日1970年1月1日0時0分0秒起經過的秒數來計時。如公元1970年1月2日0時0分0秒的Unix時間就是86400——這符合計算機的性格,反正只要簡單,好不好記是愚蠢的人類才需要考慮的。

這個計時系統被所有Unix和類Unix系統繼承下來,而且影響了許多非Unix系統,POSIX標準推出後,該時間也被稱為POSIX時間。當然,Unix並非正巧在這天誕生,就像國慶日定在10月1日一樣,這也是人類為了自己好記而選擇的,其實最早PDP-7上的UNIX系統1969年就在運行了。

人類的各種曆法中都存在「節日」的概念,有的是為了紀念某個人,有的是紀念某件事,有的則純粹由於日期本身的獨特性或趣味性,例如11月11日被稱為光棍節(因為數字都是棍子),10月11日被稱為蘿莉節(因為數字像英文的loli)……愛好節日的無聊人類也沒放過Unix「曆法」:2001年9月9日1時46分40秒,UNIX時間1000000000,被稱為第一個「億禧年」(Billennium);2005年3月18日1時58分31秒,UNIX時間1111111111,則儼然超級無敵大光棍節;2009年2月13日23時31分30秒,UNIX時間1234567890,是不是該叫阿拉伯數位元組?

「億禧年」是個值得警惕的名詞,哪怕是記憶力不好的人類也應該記得本世紀初的「千年蟲」問題(簡稱Y2K BUG):在比Unix誕生更早的計算機中,由於存儲成本過高而僅採用兩位數字表示年份,一旦到達公元2000年,計算機所表示的00年就出現混亂,並造成了全世界範圍內的巨大影響。Unix時間的第二個「億禧年」出現在公元2033年5月18日3時33分20秒,我們可以拭目以待;第三個「億禧年」出現在2038年1月19日3時14分7秒,就恐怕不會那麼順利地到來,因為在那之前,人類首先要解決類似「千年蟲」卻比「千年蟲」更加隱蔽更為棘手的「2038年問題」。

我們知道,再強大的計算機其內部都建立在二進位基礎之上,也就是說1234567890這樣的數字,在32位計算機系統的內存里實際上是01001001 10010110 00000010 11010010,這串32位二進位數中,最高位被用來表示正負符號,0代表正數,1代表負數,所以它能表示的最大數字就是01111111 11111111 11111111 11111111,即2147483647,當它用來表示Unix時間,則對應公元2038年1月19日3時14分7秒——Unix時間的第三個「億禧年」——的前一秒。再過一秒鐘,Unix時間會溢出變成10000000 00000000 00000000 00000000,首位1代表負數,因此這串二進位數相當於十進位的-2147483648,這是什麼概念?四個字:時光倒流。負數表示了一個Unix誕生之前的時間——公元1901年12月13日20時45分52秒,從而引發和「千年蟲」類似的混亂。

「2038年問題」的隱蔽之處就在於,人類這種腦子實在記不住2038年1月19日3時14分7秒這個有零有整參差不齊的時刻;而棘手之處在於,它產生的原因更接近系統底層。最簡單的解決方式是將所有計算機升級到64位操作系統,以擴展Unix時間的長度。64位二進位數的實際可用位數是63位,最大能表示到公曆的292277026596年12月4日,如果那個時候人類文明還存在的話,公元紀年很可能因為太難記而被拋棄了。理想的情況是等到2038年,64位系統已經成為主流,從而避免特意修正這個問題所需的高昂成本。

計算機32位操作系統所能表示的最大整數2147483647(即2的31次方減1)是個神奇的數字,除了會引發「2038年問題」外,它還是第8個梅森素數(目前僅發現49個),也是第3個雙重梅森素數(目前僅發現4個),1772至1867年的近百年間,這個數是已知的最大素數。


推薦閱讀:

TAG:計算機科學 | Unix | 二進位 |