go语言拥有两种浮点类型,一种是float64,每个64位的浮点数需要占用8字节,另一种是float32,占用4字节。
var p = 3.54
fmt.Printf("%T",p)
输出float64,也就是默认浮点数是float64,如果想定义float32,需要明确指定。
如果不为float64赋值,默认就是0.0。
下面的浮点数的格式化输出,%4.2f中4代表总宽度,这里需要注意,点也算宽度。2代表小数点后面有2位。%.3f是总宽度没有说明,只说明小数点后有3位。如果只有2位,那最后一位用0补充。
abc := 1.0 / 3
fmt.Println(abc)
fmt.Printf("%.3f\n", abc)
fmt.Printf("%4.2f\n", abc)
浮点数的计算会出现精度问题,虽然可以精确的标识1/3,但是在使用这个数字和其他数字进行计算的时候却会引发舍入错误。
abc := 1.0 / 3
fmt.Println(abc + abc + abc) //输出1
aaa := 0.1
bbb := aaa + 0.2
fmt.Println(bbb) //0.30000000000000004
浮点数不是表示金钱的最佳选择。解决这一问题的另一种做法是使用整数类型存储分。不过一般来说获取2位小数基本还是正确的。还有一个技巧,把乘法计算放到除法计算的前面执行,这样做法通常会得到更为精确的计算结果。
ceshi := 16.0
fmt.Println(ceshi / 5.0 * 3.0) //9.600000000000001
fmt.Println(ceshi * 3.0 / 5.0) //9.6
发现先进行乘法再除法确实是精确了。
在进行浮点数比较时,要小心计算后的浮点数出现精度问题,不要直接对值进行比较,可以使用比较的值计算差,然后判断这个差的绝对值是否足够小来判断两个浮点数是否相等。
aaa := 0.1
bbb := aaa + 0.2
fmt.Println(bbb)
fmt.Println(bbb == 0.3) //false
fmt.Println(math.Abs(bbb-0.3) < 0.0001) //true