看着小黑屏中显示的y=3.500000这段字符时,我心里没有丝毫惊讶。其实在老爹跟我说的时候我已经信了八分,剩下的两分并非是因为对老爹有所怀疑。
相反,我在主观意识上非常愿意相信老爹,因为从我记事以来,老爹从来没有骗过我。
但是老爹对我说过,对待一切都要有怀疑精神,一向便是如此的那并不代表就是对的。
所以剩下的两分便是来源于此,除此之外还多少包含一些不甘心,如果没有见到结果我真的不甘心推翻自己确信的答案。
既然正确的答案和我给出的不一样,接下来重点就应该是解决一个问题——why?
「在写程序的时候往往会用到很多数学相关的知识,甚至很多书上说数学作为程序员的基本素质之一。但是,这并不意味着写程序完全就是数学问题。
小数的精度损失就是最好的例子,在数学上能够精确表达的有限循环小数在程序中可能不能准确记录。」
老爹的这句话可谓是当头棒喝,让我内心剧震。因为我完全将程序当成了数学问题在处理!
「好了,我来跟你讲一遍这题为什么是这个答案,可要听仔细了。
首先,对于小数类型的数据,如long double、double、float三种类型的变量,无论你给它赋的值有没有小数,计算机在保存的时候默认会添加六位小数,如果不足位就添零。
题目中已经明确说明了y是double类型的变量,这是为什么在B答案3和D答案选3.000000两个选项中选择D的原因。
那么接下来说说结果为什么是3而不是3.5。
还记得昨天我跟你说过,计算机其实很笨,它只会忠实地执行我们给它下达的指令么?」
「记得。」
我点了点头。
「嗯,其实这一点在这道题上得到了充分的展现。
计算机真的很笨,所以我们在下达指令的时候一定不能让它感到迷惑,否则程序必定出错!这一点一定要记住!
计算机在对数据进行数学运算的时候,整数和小数是严格分开的。如果表达式中的变量全部都是整数,那么计算机就进行整数计算,得到的结果也是整数。这就意味着在进行整数除法的时候如果产生了小数,小数部分会被丢弃掉!
比如说1/4,在数学上等于0.25,但在程序中则等于0。」
「哦,我知道了!这道题的结果之所以是3,是因为在计算3/2的时候得到的结果是1!」
我恍然大悟道。
「absolutely!」
「原来如此,那如果我想得到正确的答案怎么办?」
「如果想要正确地保存运算结果为小数需要保证两个条件:第一是接收运算结果的变量必须是小数类型,第二是表达式中有小数出现。
刚刚跟你说了,计算机在进行数学运算的时候整数和小数是分开。但是当计算机发现计算的表达式中包含了小数,它就会自动将所有的变量转换为小数来计算。就拿这道题来说,如果把被除数修改成3.0或者把除数修改成2.0就能得到和数学上相等的答案了。」
按照老爹所说,还真的得到了正确的答案。
「老爹啊,按照你所说的,计算机发现了表达式里边有小数,就会把所有变量转换为小数进行运算。可是变量a已经是double型的了,计算机应该把被除数和除数转换为小数计算,就应该得到正确的结果了啊。可是……」
我疑惑道。
「嘿嘿,你偷换概念了哦。我说的是变量而不是表达式,而3/2是个表达式!虽然a是个double型变量,然而计算机在计算的时候只会把3/2的计算结果转换为小数,但是在这个时候小数位已经被丢弃了。所以我说计算机真的很笨,就是这个原因了。」