原因:因为计算机智能识别0和1,所以不管是整数还是小数,都是以二进制的形式保存在内存中。浮点数是分为符号、尾数、阶码三部分来保存的。(F = (-1 ^ s)X(1 . M)X(2 ^ e)),s为符号位,0或1。M是尾数,指具体的小数,用二进制表示。e是比例因子的指数,是浮点数的指数。浮点数因为用二进制表示,位数很多时候不太够,无法准确的表示数字,所以运算起来肯定会产生不准确的精度问题。
会遇到精度问题的情形:
1、数值比较起来不相等。(无法精确定位值,可以通过大于或者小于来避免,或者是采取相差数值小于某精度来比较)
2、数值计算不确定。(不精确的数,当然会产生不精确的结果)
3、不同设备的计算结果不同。(因为硬件和系统不同,计算结果可能会出现偏差)
精度问题的解决方案:
1、简单方法:由一台机器进行计算结果,只计算一次,认定该值为精确结果,然后把该值传递,只通过该变量来判断结果。(能避免多次计算,而且排除了不同机器的计算差异干扰)
2、改用int或long类型来替代浮点数:可以将浮点数转换为整数,然后再进行计算。(需要注意转化后的数值位数问题,防止超限)
3、用定点数保持一致性并缩小精度问题:定点数,是指将浮点数的整数部分和小数部分拆分,都用整数来保存的特殊形式数。(C#的decimal类型就是内部用定点数来实现的。该类型需要对数值进行转换操作,会额外增加大量运算以及额外占用内存空间,所以并不太适用不需要高精度计算的开发产品)
4、用字符串代替浮点数:因为运算时CPU和内存的消耗特别大,所以一般只用于少量的需要极高精度的计算。