代码之谜(零)- 开篇/前言/序
最近看本文評論,爭議很多,我先說說這篇文章的前世今生吧。
我原文標題是『代碼之謎 - 開篇/前言/序』,副標題是『其實,你不懂代碼』,本來打算用“其實,代碼中的運算符不等價于數(shù)學(xué)符號”。原文我寫于2010年底,當時寫在 evernote 中,用了”群“、”域“、”集合“、”關(guān)系“的概念解釋了計算機中用二進制表示的離散的數(shù)和現(xiàn)實中連續(xù)的數(shù)之間的關(guān)系和區(qū)別。
前幾天QQ群里有人問道,遂打算寫一個系列,用比較「貧」的語言把他們講述出來。
原文首發(fā)在我的博客: http://justjavac.com/codepuzzle/2012/09/25/codepuzzle-introduction.html, 因為我也不能保證我的博客空間總是穩(wěn)定的,所以,如果博客訪問不了,可以到iteye 或 CSDN 查看這篇文章,還可以順便看看熱心網(wǎng)友的評論。
正文分割線
答應(yīng)了群里的兄弟們要更新博客,結(jié)果回家又是洗衣服做飯的,轉(zhuǎn)眼已經(jīng)10點多了。
趁洗衣機正在轉(zhuǎn)的功夫,打開 Evernote 找到了以前的幾段 javascript 代碼,本著人性本賤(咳,咳,該死的輸入法,更正「人性本薦」)的精神,給大家共享一下,不定期更新,算是我「代碼之謎」系列的開篇吧。
我喜歡讀一些讓人震驚的書,比如『哥德爾、艾舍爾、巴赫書:集異璧之大成』,比如『從一到無窮大』,讀完后張大嘴巴,「哇噻,太不可思議了,太令我震驚了」。本系列博客的目的之一就是讓每個閱讀過的人在思維方式上有所改變,變得更理性,更加會思考,會學(xué)習(xí)。
本系列說來話長,從10年開始構(gòu)思,當時寫在 evernote 里面,名字叫『理性,像數(shù)學(xué)家一樣思考』,廢話少說,言歸正傳,貼代碼吧
第一段代碼:
function foo1(a){return a + '01'; }foo1(01);第二段代碼:
function foo2(a){return a + '010'; }foo2(010);第三段代碼: (注: 這不是 javascript 的問題,而且所有語言的問題,歸根結(jié)底是 IEEE 標準中二進制浮點運算的問題,關(guān)于浮點數(shù)的詳細問題請閱讀代碼之謎 - 浮點數(shù),「為什么沒有鏈接呢,呵呵,因為我還沒有寫,正在整理中」。)
console.log(0.2 + 0.4);第四段代碼就相對來說簡單多了: 參考我一些發(fā)布的這篇為什么 ++[[]][+[]]+[+[]] = 10?。
[4,[3,2]][1][0]; // 3分割線
2012年9月25日 22時25分 更新
還是忍不住,睡前想嘮叨幾句。
也許很多人第一次接觸編程時,對 i = i + 1 都感到百撕不得騎姐(咳,我就說了嘛,必須得換一個輸入法了,更正「百思不得其解」)。
“i加上1怎么可能和i相等呢?”
后來慢慢知道了,不,確切的說,是慢慢地接受了,接受了=是賦值(前提是你學(xué)的不是pascal,我的入門語言就是它),因為你可能根本沒有思考,只是被動接受。
再后來,我們學(xué)了 if, 開始寫分支代碼:
if (a >3) { // do something }if (a < 5) {// do something }但是當我們寫出 if (3 < a < 5) 時,居然報錯了,又是百撕不… 后來被教導(dǎo)了,這么寫是錯的,應(yīng)該 if (a>3 && a<5)。于是我們又開始接受了,認為這么寫是理所當然的,而且以后的代碼都是這么寫的。
直到有一天,你看了 python 的入門手冊,尼瑪,居然逆天的出現(xiàn)了 'if 3 < a < 5:',當時絕對又震驚了,“怎么可以這么寫?”。難道你忘了,N年前你就是這么寫的,而且當時你不也認為3 < a < 5 是理所當然的嗎(任何一個高中生都會同意這種寫法),為什么你現(xiàn)在又開始覺得 3 < a < 5 是種逆天寫法呢,因為你在這幾年的編程生涯中,已經(jīng)被動接受了太多太多的東西,而且使你根本就不曾思考過,這也是我寫「代碼之謎」系列的初衷。
當你被告知了,在編程中=是賦值的意思(其實他們沒有告訴你,只是大部分語言這樣,還有很多語言不是這樣,比如pascal中:=是賦值,比如basic/VB中=即是賦值也是判斷),但是=如果不是相等的話,那肯定有表示相等的,對,就是==,或者===。
不管是==還是=,「相等」到底是什么意思呢?=或者==或者===,即使以后會出現(xiàn)====,到底和數(shù)學(xué)的「相等」有多少出入呢?
知道我們遇到了傳說中的NaN(很多人認為NaN既然表示Not A Number,那么他就是語言定義的一個東東,根本不存在,這是錯誤的,NaN是在IEEE浮點數(shù)規(guī)范中明確定義的,包括本系列后面后提到的+0和-0問題),它不等于任何值,而且,它居然不等于它自己。
一個數(shù)居然不等于它自己,其實確切的說,是 NaN == NaN 居然返回 false, 甚至 NaN === NaN 也返回 false。是 NaN 的問題,還是==或者===的問題,抑或這根本就是相等這個概念的問題。
在集合論中,相等的三要素,不管是==還是===,都無法滿足,所以說,===根本就不是相等(如果你讀過數(shù)學(xué)的「群倫」就更明白了)。
相等(等價)的三要素
當我們看到這幾條定理時,我們從來沒有懷疑過。脫離了數(shù)學(xué),我們進入了編程領(lǐng)域,當我們遇到了NaN,我們知道了,在IEEE的數(shù)字表示規(guī)范里面,「自反省」是不被滿足的,那么傳遞性和對稱性呢? 如果你找到了反例,可以留言。
也許你說,相等/等于/全等/等價這些比較特殊,其它的應(yīng)該都會滿足吧。我只能告訴你(說通俗一點),以前的所有定理、公理都只適用于一個領(lǐng)域,當它進入另一個領(lǐng)域我們就不能把它當作理所當然的,也許它沒有問題,比如 1+2=3,但也許這只是一個巧合,上面我就提到了 0.2+0.4 就不等于 0.6。
計算機和現(xiàn)實最大的不同(也是問題的根源)就是,世界是連續(xù)的,而計算機是非連續(xù)的,是離散的。以前我們學(xué)校圖書館有很多「計算機數(shù)學(xué)」或者「離散數(shù)學(xué)」之類的書,我現(xiàn)在都不明白,里面寫的那些數(shù)學(xué),是設(shè)計計算機的工程師讀呢,還是使用計算機的程序員讀呢?里面的內(nèi)容簡直就是大雜燴嘛。什么是離散數(shù)學(xué)呢?我的理解,不連續(xù)的數(shù)學(xué)都是離散數(shù)學(xué)。比如量子論里面用到的數(shù)學(xué),就是離散數(shù)學(xué)。
其它算數(shù)定律或者定義有不滿足的嗎?
再舉一例,上小學(xué)剛學(xué)乘法運算的時候老師就告訴我們,3x4就是4個3相加,下面這個例子再次顛覆你的想法。
console.log(0.1 * 10); console.log(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);寫完睡覺,如果大家有什么更好的例子,歡迎補充。
from: http://justjavac.com/codepuzzle/2012/09/25/codepuzzle-introduction.html
總結(jié)
以上是生活随笔為你收集整理的代码之谜(零)- 开篇/前言/序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于编程的胡扯
- 下一篇: 你为什么薪水那么低(二)之 生产力