既然float和double都存在精度丢失的问题,为什么还要设计这2种类型呢?

既然floatdouble都存在精度丢失的问题,为什么还要设计这2种类型呢?
直接用Decimal不就好了?
这里主要说的是在数据库字段类型,Java或者C#等情况。


看了各位大佬的观点后,我再矫正一下我想问的问题。
就是,很多情况出现精度丢失,可能对于计算结果,相差不会特别大。
但是,在显示上,就会很难看。当然,在结果上再加上一个四舍五入之类的逻辑,也能解决,就是,很麻烦,因此,在中小型软件上,对内存磁盘要求不高的环境中,是否无脑decimal会比较好?


回答:

float/single 对标的是 int32,4 字节、32 位;double 对标的是 int64/long,8 字节、64 位

而 decimal 是 16 字节、128 位。(这里指在大多数编程语言中,在 MySql 中的 decimal 类型比较特殊,本质是一种特殊的 struct,是不定长的,这里先不展开讲了)。它的所谓高精度是以牺牲范围为代价的,而且占用内存更大、计算性能更低(开了编译优化以后慢个百八十倍太正常了)。

而“精度”这个玩意儿,本身就是人为控制的,在很多场景下精度丢失是可以忍受的 ———— 现实世界中的数学运算本身就充斥着舍入、极限、积分等等并不精确的情况。为什么现实中可以忍受有限的精度、到计算机里反倒必须“精确”了?

按照题主的理论,int64 能表示的范围比 int32 大多了、所有 int32 都全能用 int64 “完美”存储,为什么还要设计出 int16/short、int8/byte 等等“没用的”数据类型?全都用 int64 存整数岂不美滋滋?


【补充】

我总算是明白了,有些人的心理活动大概是这样的:


回答:

精度丢失的本质不是类型的错吧,是数学的错,不对,好像又是物理的错。

为什么要有呢?有医生就不要护士了吗?

为什么不直接用Decimal呢?用的很多呀,河这边是别墅区,河那边是小高层,

给你一张A4纸,一根记号笔,一根0.5的中性笔,抄写一篇文章,要求能醒目的尽量醒目,但是能写更多的字更好。小明和小张都抄了不少,一向节俭的老师选择了字数更多的小明,眼神不好的校长选择了字少但是字体更大的小张,他们都有光明的未来

==== 那我也补充一点吧 ====

还是kanye终结了比赛

其实说实话,世上本没有精度,只有这个

0.9999...=1


回答:

简单来说,这是一个性能和方便性权衡的问题。

单精度(float)和双精度(double)浮点数,在很多语言中都属于基本数据类型,他们用若干个字节存储二进制的有效数字,特定的字节来保存小数点的位置,这是一种非常高效的存储模式,CPU也有对应的浮点运算指令集来实现加减乘除这样的计算。

而Decimal数据类型就完全不同了,因为二进制小数,本质上无法精确表达十进制小数(比如3.3,转成二进制就是无限不循环小数),所以Decimal是需要复杂的数据结构的,计算也相当繁琐。通常各种语言都是先用字符串保存我们定义好的十进制数,内部用一个变量保存小数的位置,再把它缩放为对应的整数(比如3.53,对应的整数就是353,小数位为2),然后跟另外一个Decimal的计算,是按整数进行的,当然位数要对齐(比如3.53+2.4,会变成353+240),输出的时候,再根据小数点的位置,重新生成对应的字符串。(具体实现方法,可以参考这个decimaljs项目,是我好多年前,为了在浏览器中计算钱数写的)

这样一来,Decimal倒是可以进行精确小数运算了,但执行速度比浮点数低了好几个数量级。而我们很多时候的运算,是不需要那么高精确度的,比如三维渲染,只要像素点在合适的位置就好了,计算误差可以忽略,这就是浮点数大显身手的地方。

当然,涉及到钱的问题,通常还是需要精确表达的,所以Decimal经常用于财务、采购、买卖相关的逻辑。


回答:

  1. 很多场景不需要那么高的精度
  2. float和double需要的内存/存储空间更少,计算效率更高


回答:

这个是工程实践中技术均衡的结果。

毕竟很多计算本身就不能简单的用数字表示结果,比如你表示一下sqrt(2),但工程实践中有时又必须有能够直接用数字表示的结果,这时,在许可范围内允许很小的失真也是客观需求,所以所有的复杂计算结果,在数字表示时都必然出现失真。计算机作为人类用作处理信息的工具,也具有类似特征。

在金融中,其实有时是采用整数来处理(比如以分表示的整数),但计算结果中一样会失真(比如计息结果一般个人只到分,中间过程到0.1分),但即使这样,一样可能存在中间结果失真的可能,特别是对于既有大的部分,又有很小的部分的数字计息计算中,一样可能出现分部计息相加和不等于总和直接计息的情况(无论多精确的系统,都可能出现这样的情况,只要分的部分足够多,都可能出现问题的!)。所以工程实践中,对此需要进行均衡考虑,追求绝对完美是不适用于很多工程实践的。


回答:

如果涉及计算或数值比较或货币类,无脑选择Decimal即可。
其他情况下,对精度要求不高,就选float和double,设计数据库的时候,这个字段的大概什么样,你心理没点B数?

以上是 既然float和double都存在精度丢失的问题,为什么还要设计这2种类型呢? 的全部内容, 来源链接: utcz.com/p/944467.html

回到顶部