关于Go的浮点数骗局
骗局前言
某一天,某人问我,Go里面可以用浮点数进行比较吗? 某同事答约,可以的。那到底可以不可以。"Talk is Cheap, Show Me the Code."
代码验证浮点数精度
我找到了网络上比较有名的验证浮点数精度的例子,看看Go能不能通过
func testPrecision(){
a := 0.1
b := 0.2
c := 0.3
if a + b == c {
fmt.Printf("Isprecision:%v", true)
}else{
fmt.Printf("Isprecision:%v", false)
}
}
但是很不幸,答案是否定的,输出了false。但是为什么呢? 这是一个可以被编程语言解决的问题吗?
Isprecision:false
浮点数的计算机存储
现在回想一下大学教授的计算机组成原理的知识。计算机上只对0,1进行保存。对于整数,我们非常简单地解决了这个问题。只需要在存储字节地最高位腾出一个位来表示该整数的正负即可。
但是在计算机中,浮点数的存储可十分复杂。在计算机发展的过程中,出现过许多不同的浮点数存储办法。其中包括以下三种:
- 定点数表示方法,即固定整数和浮点数的字节大小。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的 NUMBER 数据类型就是利用