前世今生
---------2012年9月28日 13时32分 新增-------
最近看本文评论,争议很多,我先说说这篇文章的前世今生吧。
我原文标题是『代码之谜 - 开篇/前言/序』,副标题是『其实,你不懂代码』,本来打算用“其实,代码中的运算符不等价于数学符号”。原文我写于2010年底,当时写在 evernote 中,用了”群“、”域“、”集合“、”关系“的概念解释了计算机中用二进制表示的离散的数和现实中连续的数之间的关系和区别。
前几天群里有人问道,遂打算写一个系列,用比较「贫」的语言把他们讲述出来。
原文首发在我的博客: http://justjavac.com/codepuzzle/2012/09/25/codepuzzle-introduction.html, 因为我也不能保证我的博客空间总是稳定的,所以,将这篇文章发布到了iteye,还可以顺便看看热心网友的评论。
----------正文分割线-------------
答应了群里的兄弟们要更新博客,结果回家又是洗衣服做饭的,转眼已经10点多了。
趁洗衣机正在转的功夫,打开 Evernote 找到了以前的几段 javascript 代码,本着人性本贱(咳,咳,该死的输入法,更正「人性本荐」)的精神, 给大家共享一下,不定期更新,算是我「代码之谜」系列的开篇吧。
我喜欢读一些让人震惊的书,比如『哥德尔、艾舍尔、巴赫书:集异璧之大成』,比如『从一到无穷大』,读完后张大嘴巴,「哇噻,太不可思议了,太令我震惊了」。 本系列博客的目的之一就是让每个阅读过的人在思维方式上有所改变,变得更理性,更加会思考,会学习。
本系列说来话长,从10年开始构思,当时写在 evernote 里面,名字叫『理性,像数学家一样思考』,废话少说,言归正传,贴代码吧
第一段代码:
function foo1(a){
return a + '01';
}
foo1(01)
第二段代码:
function foo2(a){
return a + '010';
}
foo2(010);
第三段代码: (注: 这不是 javascript 的问题,而且所有语言的问题,归根结底是 IEEE 标准中二进制浮点运算的问题,关于浮点数的详细问题请阅读 代码之谜 - 浮点数,「为什么没有链接呢,呵呵,因为我还没有写,正在整理中」。)
console.log(0.2 + 0.4);
第四段代码就相对来说简单多了: 参考我一些发布的这篇为什么 ++[[]][+[]]+[+[]] = 10?。
[4,[3,2]][1][0]; // 3
-----------------------分割线-----------------------------
2012年9月25日 22时25分 更新
还是忍不住,睡前想唠叨几句。
也许很多人第一次接触编程时,对 i = i + 1 都感到百撕不得骑姐(咳,我就说了嘛,必须得换一个输入法了,更正「百思不得其解」)。
“i加上1怎么可能和i相等呢?”
后来慢慢知道了,不,确切的说,是慢慢地接受了,接受了=是赋值(前提是你学的不是pascal,我的入门语言就是它),因为你可能根本没有思考,只是被动接受。
再后来,我们学了 if, 开始写分支代码:
if (a >3) {
// do something
}
if (a < 5) {
// do something
}
但是当我们写出 if (3 < a < 5) 时,居然报错了,又是百撕不… 后来被教导了,这么写是错的,应该if (a>3 && a<5)。 于是我们又开始接受了,认为这么写是理所当然的,而且以后的代码都是这么写的。
直到有一天,你看了 python 的入门手册,尼玛,居然逆天的出现了 ‘if 3 < a < 5:’,当时绝对又震惊了,“怎么可以这么写?”。 难道你忘了,N年前你就是这么写的,而且当时你不也认为 3 < a < 5 是理所当然的吗(任何一个高中生都会同意这种写法), 为什么你现在又开始觉得 3 < a < 5 是种逆天写法呢,因为你在这几年的编程生涯中,已经被动接受了太多太多的东西,而且使你根本就不曾思考过, 这也是我写「代码之谜」系列的初衷。
当你被告知了,在编程中=是赋值的意思(其实他们没有告诉你,只是大部分语言这样,还有很多语言不是这样,比如pascal中:=是赋值,比如basic/VB中=即是赋值也是判断), 但是=如果不是相等的话,那肯定有表示相等的,对,就是==,或者===。
不管是==还是=,「相等」到底是什么意思呢?=或者==或者===,即使以后会出现====,到底和数学的「相等」有多少出入呢?
知道我们遇到了传说中的NaN(很多人认为NaN既然表示Not A Number,那么他就是语言定义的一个东东,根本不存在,这是错误的,NaN是在IEEE浮点数规范中明确定义的,包括本系列后面 后提到的+0和-0问题),它不等于任何值,而且,它居然不等于它自己。
一个数居然不等于它自己,其实确切的说,是 NaN == NaN 居然返回 false, 甚至 NaN === NaN 也返回 false。是 NaN 的问题,还是==或者===的问题,抑或这根本就是相等这个概念的问题。
在集合论中,相等的三要素,不管是==还是===,都无法满足,所以说,===根本就不是相等(如果你读过数学的「群伦」就更明白了)。
相等(等价)的三要素
- 自反省: A等于A
- 对称性: 如果A等于B,那么B等于A
- 传递性: 如果A等于B,而且B等于C,那么A等于C
当我们看到这几条定理时,我们从来没有怀疑过。 脱离了数学,我们进入了编程领域,当我们遇到了NaN, 我们知道了,在IEEE的数字表示规范里面,「自反省」是不被满足的,那么传递性和对称性呢? 如果你找到了反例,可以留言。
也许你说,相等/等于/全等/等价这些比较特殊,其它的应该都会满足吧。 我只能告诉你(说通俗一点),以前的所有定理、公理都只适用于一个领域,当它进入另一个领域我们就不能把它当作理所当然的,也许它没有问题,比如 1+2=3,但也许这只是一个巧合, 上面我就提到了 0.2+0.4 就不等于 0.6。
计算机和现实最大的不同(也是问题的根源)就是,世界是连续的,而计算机是非连续的,是离散的。 以前我们学校图书馆有很多「计算机数学」或者「离散数学」之类的书,我现在都不明白,里面写的那些数学,是设计计算机的工程师读呢,还是使用计算机的程序员读呢?里面的内容简直就是大杂烩嘛。 什么是离散数学呢?我的理解,不连续的数学都是离散数学。比如量子论里面用到的数学,就是离散数学。
其它算数定律或者定义有不满足的吗?
再举一例,上小学刚学乘法运算的时候老师就告诉我们,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);
写完睡觉,如果大家有什么更好的例子,欢迎补充。




相关推荐
这是我读《python机器学习及实践-从零开始通往kaggle竞赛之路》时自己写的代码,包括了3.2节之前的所有代码,详见www.xxy.ink/467.html,相对于书中代码略有改动,比如分类加入了混淆矩阵、修改了书中报错的部分等,...
自学系列(零基础学小程序)---小程序实现简单的倒计时(源代码+截图)自学系列(零基础学小程序)---小程序实现简单的倒计时(源代码+截图)自学系列(零基础学小程序)---小程序实现简单的倒计时(源代码+截图)自学系列...
动软代码生成器 V2.76版,请支持正版。 修改DAL.cmt模板文件: 1、必须增加该命名空间 using MySql.Data.MySqlClient; 2、部分的 SqlParameter 修改为 MySqlParameter 3、获取前几行数据时,修改为 limit 4、参数...
标题中的"GARCH-MIDAS、DDC-MIDAS模型MATLAB代码"指的是在金融计量领域中,使用MATLAB编程实现的两种重要的模型:GARCH-MIDAS(Generalized Autoregressive Conditional Heteroskedasticity with Mixed Data ...
根据压缩包子文件的文件名称 "匿名拓空者资料包-20171217",我们可以推断这个文件夹很可能包含了整个飞控系统的资源集合,包括但不限于源代码文件、项目文档、编译说明、测试数据、示例程序等。这样的资源对于想要...
今天简化了金山的开源代码,用来学习一下,先谢谢金山的开源精神了,呵呵···直接弄最简单的,窗口见下图,关键代码如下,全部的代码放附件里吧。分析中关于累的继承机制等没有详细的说明了,在函数申明中我会用...
代码随想录-八股文 PDF 代码随想录-八股文 PDF 是一个涵盖了程序员学习必备的内容的知识星球精华,总结了包括 C++、Java、Go 在内的多种编程语言,数据结构和算法、操作系统、数据库、计算机网络、设计模式、Linux ...
基于ISO-14229-1 Road vehicles — Unified diagnostic services (UDS) 代码生成工具。未经过本人同意不能用于商业目的买卖,代码中有本人联系方式,可技术讨论。
ucos-ii全部源代码 ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码 ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码ucos-ii全部源代码
各行业零代码、低代码应用案例
在编程世界中,保持代码整洁和格式化是至关重要的,这不仅有利于代码的可读性,也有助于团队协作和代码维护。针对JS(JavaScript)和HTML(超文本标记语言)这两种广泛使用的前端开发语言,有多种代码格式化工具可以...
在多目标优化领域,Matlab是一种常用的编程工具,因为它提供了丰富的数学函数库和直观的编程环境,...如果你是这个领域的研究者或学生,通过学习和使用PlatEMO,你可以更深入地理解和掌握多目标优化算法的原理和应用。
综上所述,"1553B代码 FPGA代码"涉及到的不仅是1553B协议的理论知识,还包括了FPGA设计和实现的实践经验。对于航空航天领域的工程师而言,理解和掌握这部分知识是至关重要的,因为它直接关系到系统通信的可靠性与...
通过深入理解这些知识点,并结合提供的代码,你可以在PyCharm中运行和调试股票预测SVM模型,从而提升对股票市场的理解和预测能力。记住,实际操作时,要结合实时数据和市场动态,以获取更准确的预测结果。
在Word中插入代码并实现与IDE(集成开发环境)类似的显示效果,主要是通过设置行号和应用代码高亮样式来实现。以下将详细介绍如何操作。 首先,为了在Word中显示代码行号,你可以采取以下步骤: 1. **插入代码样式...
小波特征提取算法代码,小波异常值提取代码,隐马尔可夫预测代码,元胞自动机代码演示案例,智能算法之粒子群优化算法代码,智能算法之模拟退火算法代码,智能算法之遗传算法代码,主成分分析代码,主成分分析降维...
为了充分利用这些资源,你需要理解MCMC的基本原理,熟悉MATLAB编程,并可能需要调整代码以适应你的具体问题。在使用时,确保遵循源代码的许可协议,并且对代码进行适当的测试和验证,以确保其正确性和适用性。
在实际开发中,遵循华为代码规范可以显著提升代码质量,减少因不规范代码引发的bug,提高团队间的沟通效率。通过IDE的插件或者配置,可以实现代码规范的实时检查和自动修复,进一步保证代码一致性。 最后,压缩包中...
在压缩包内的文件“draw05_29_02”可能是该项目的源代码文件之一,很可能包含了实现这些功能的关键函数和算法。为了进一步理解和使用这个项目,需要具备C++编程基础,以及对数控加工和G代码的了解。通过阅读和分析源...