除了整数和字符串,Java还有两种用得比较多的数据类型是长整型和浮点型,但这两种类型用不好会引起很多麻烦。比如,金额千万别使用float数据类型存储,不然不仅没有工资,可能把自己卖了都不够弥补公司的损失,看代
码:
float f1 = 0.9f; float f2 = 0.1f; System.out.println(f1 - f2);
执行之后,结果并不是预想中的0.8,而是0.79999995。可以自己写代码然后执行试试看。
为什么会这样?
因为人类认识十进制,但是计算机只认识二进制,所以在计算机“眼里”,且都是二进制:
0.9 = 0.1110011001100110011
0.1 = 0.0001100110011001101
这样一来,两个二进制小数相加,然后再经过计算机的规约化、指数偏移、拼接等特殊处理,就造成了精度丢失。double数据类型也是一样的。
而且有的开发同学还喜欢「地板除」,就是10 / 3 = 3.3333333......,然后有的同学就把0.33333......给直接省掉了。这个如果是一些企业内部的应用倒还无所谓,但是如果放到互联网上,尤其是像BAT、TMD这样的大公司,这就是完全不可接受的处理方式。可以试想一下:如果BAT公司一天有100万订单,每个订单少收0.3333333......,那一个月下来,开发这个功能的工程师估计要惨了!
所以,在互联网公司,尤其是用于存储金额数据时,一般只用int类型,float和double这种数据类型只能用作科学或者是工程计算场景。
例如9.9(元),那么实际上在数据库中存储的是990(分),甚至9900(厘),而且打折、价格计算时,一般都会注意尽量不出现小数。
至于float和doule的区别,没有必要去纠结用哪种类型,因为实际开发中几乎用不到。所以这两种类型的特性、使用场景,在真正需要用的时候再去了解就行了。
另一种稍微要注意的数据类型就是长整型,只需要说一点:在分布式ID生成算法中,有一种雪花算法,它产生的就是20位长整型。这种ID数据如果要传给前端,就会出现精度丢失,例如:服务端的生成的ID是1242735526042206228,但前端拿到的值却是1242735526042206200,出现了两位数的精度丢失。所以在传给前端时,需要将这种长整型转换为字符串。
这个问题也牵扯出另一个问题:不同编程语言组成异构系统时,需要格外注意数据类型之间的转换。