浮点数和十进制数据类型的区别

40 浏览
0 Comments

浮点数和十进制数据类型的区别

使用float和decimal数据类型在MySQL中有什么区别?在什么情况下应该使用哪个?

0
0 Comments

浮点数和十进制数据类型的区别

MySQL最近改变了它们存储DECIMAL类型的方式。过去,它们存储了每个数字的字符(或nybble),其中包含了数字的ASCII(或nybble)表示,而不是使用二进制补码整数或其衍生物。目前的DECIMAL存储格式是一系列1、2、3或4字节的整数,其位被串联起来创建一个带有隐含小数点的二进制补码数,该小数点由您定义,并在您声明列并指定其DECIMAL大小和小数点位置时存储在数据库模式中。

举个例子,如果你使用一个32位整数,你可以存储从0到4,294,967,295的任何数字。这只能可靠地涵盖999,999,999,所以如果你丢弃2位并使用(1<<30 -1),你就不会损失任何东西。用4字节来覆盖所有9位数比用32位中的4个ASCII字符或8个nybble数字更有效率。(nybble是4位,允许0-15的值,比0-9所需的更多,但你不能通过使用3位来消除这种浪费,因为这只涵盖了0-7的值)

MySQL在线文档上使用DECIMAL(18,9)作为示例。这是小数点前后9位数字,如上所述,需要以下存储。

作为18个8位字符:

144位

作为18个4位nybbles:

72位

作为2个32位整数:

64位

目前,DECIMAL支持最大65位数字,作为DECIMAL(M,D),其中M允许的最大值为65,D允许的最大值为30。为了不需要每次都要求9位数字,使用小于32位的整数使用1、2和3字节整数来添加数字。由于某种不符合逻辑的原因,使用了带符号整数而不是无符号整数,并在这样做时,丢失了1位,导致以下存储能力。对于1、2和4字节的整数,丢失的位不重要,但对于3字节的整数来说,这是一场灾难,因为由于丢失了那个单独的位,整个数字都丢失了一个数字。

使用7位整数:

0 - 99

使用15位整数:

0 - 9,999

使用23位整数:

0 - 999,999

(使用24位整数为0 - 9,999,999)

1、2、3和4字节整数被串联在一起形成"位池",DECIMAL使用它来精确地表示数字,将其表示为二进制补码整数。小数点不存储在其中,而是隐含的。这意味着数据库引擎不需要将ASCII转换为整数来将"数字"转换为CPU识别的数字。没有舍入,没有转换错误,它是一个CPU可以操作的真实数字。

对于存储效率而言,由于浮点数的指数附加到每个浮点数上,隐含了小数点的位置,因此它具有大量多余的信息,对于数据库工作来说效率低下。在数据库中,您已经知道小数点在哪里放置,表中每一行对于DECIMAL列的值只需要查看那个唯一的小数点位置规范即可,该规范存储在模式中作为DECIMAL(M,D)的参数的隐含M和D值。

关于要为各种应用程序使用哪种格式的许多评论都是正确的,所以我不会过多强调这一点。我在这里写这些内容是因为维护链接的MySQL在线文档的人对以上内容一无所知,经过一轮又一轮越来越令人沮丧的尝试后,我放弃了。他们对自己所写的东西理解得非常糟糕,这在他们呈现的主题上非常混乱和几乎无法理解。

最后,如果您需要高精度浮点运算,过去20年来浮点代码取得了巨大的进步,96位和四重精度浮点的硬件支持即将到来,但如果操作存储值很重要,那么有很好的任意精度库可用。我认为从英特尔的Hazwell架构开始,AVX-2操作可以在256位整数上进行,覆盖77位数字可能表示的每个可能值,可以用来直接操作DECIMAL的扩展精度整数。使用硬件而不是软件,性能将提高5-10倍。2^256 = 115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640,564,039,457,584,007,913,129,639,936(78位)

英特尔的矢量处理器现在支持512位数学运算。这将覆盖154位数字。2^512 = 13,407,807,929,942,597,099,574,024,998,205,846,127,479,365,820,592,393,377,723,561,443,721,764,030,073,546,976,801,874,298,166,903,427,690,031,858,186,486,050,853,753,882,811,946,569,946,433,649,006,084,096(155位)

0
0 Comments

浮点数(float)和十进制(decimal)数据类型之间的区别

在大多数环境中,"float"是一种二进制浮点类型。它可以准确地存储二进制值(在某种程度上),但不能准确地存储许多十进制值。浮点数最适合用于科学计算。对于大多数业务数学来说,它们不合适,错误使用浮点数会给您带来麻烦。许多十进制值无法在二进制中精确表示。例如,0.1就无法精确表示,因此您会看到奇怪的结果,如1.0 - 0.1 = 0.8999999。

十进制(decimal)存储十进制数。十进制是大多数商业数学的良好类型(但任何内置的“money”类型对于财务计算更合适),它的值范围超过整数类型提供的范围,并且需要分数值。顾名思义,十进制是为十进制数设计的-它们可以准确地存储十进制值(同样,到一定程度)。

问题原因:用户想要将十进制数存储到数据库中,但不确定使用float类型还是decimal类型更适合。

解决方法:取决于数字的用途。如果数字用于比较和显示目的,则应该使用十进制(decimal)类型。但是,更好的解决方法是与经理或客户详细讨论数据的具体用途,并根据实际情况选择合适的类型。

实际上,当前float和DECIMAL以相同的方式存储它们的数字。区别在于如何使用这些数字。DECIMAL使用所有位来构成一个二进制补码整数,并具有一个隐含的小数点。浮点数有两个整数,并且一个整数将另一个整数提高到某个幂。基数和指数都是二进制补码整数。

虽然你的回答可能在技术上是正确的,但对于float是二进制类型的强调掩盖了它们存储数据的方式的重点。一个浮点数提高到一次幂是一个整数,并且以完全相同的方式存储。事实上,对于80位精度的浮点数,基数是int64。相反,如果你编写一个为整数提高幂的库,你将遇到与整数、DECIMALS、罗马数字或棒棒糖相同的问题。不是存储导致“舍入误差”,而是库对数学运算的处理方式。

在没有给出足够参数来指示OP关注的领域的情况下,很难知道什么是适当的回应。通常,DECIMAL可以存储更大的数字,并且数学库可以满足会计师的期望,而双精度浮点数是一种效率较低的存储介质,具有高度优化的数学库-这可以更好地满足科学家和金融(而不是会计师)的期望。

0
0 Comments

浮点数(float)和小数(decimal)数据类型之间的区别

在上述内容中,MySQL的用户在创建名为numbers的表后进行了一系列操作。

问题的原因:

用户想要了解浮点数和小数数据类型之间的区别,特别是在进行除法操作时两者的表现。

解决方法:

用户创建了一个名为numbers的表,其中包含一个小数列(a)和一个浮点数列(b)。然后用户向表中插入了值为100的记录。接下来,用户执行了一个查询语句,计算a列和b列分别除以3的结果,并将结果与3相乘。

查询结果如下:

:= (a/3): 33.333333333

:= (b/3): 33.333333333333

+ + : 99.999999999000000000000000000000

+ + : 100

从查询结果可以看出,小数类型在除法操作中的行为符合预期,它截断了余数,因此丢失了1/3的部分。因此,在进行求和操作时,小数类型更适合使用。

然而,在除法操作中,浮点数类型更为合适。当然,这只是在某种程度上成立。也就是说,使用小数类型并不能提供“绝对可靠的算术运算”。

另外,一位用户提到了一个有趣的测试案例。很多年前,C库的数据转换函数在将ASCII转换为浮点数时会产生微小的差异,与SQL Server中的值进行比较时常常出现这种情况。然而,现在很少出现这种情况。因此,进行测试是最好的策略,因为最好确切地了解到底有哪些权衡。

同时,还有一位用户指出,实际上小数的加法是错误的。如果将33.333333333加三次,是不会得到100的。如果将100除以3,也不会得到一个没有重复尾数的有理数,因此无法将其乘以3得到100。用户强调,从逻辑上讲,我们知道1/3 + 1/3 + 1/3应该等于3/3即1,但是这类有理数不允许我们这样做。浮点数的答案是正确的,但是会让会计师非常讨厌。

最后,还有一个用户提到了一个技术上的问题,即是否给出了99.999999999000000000000000000000这个小数,这在技术上是正确的。

浮点数和小数数据类型在进行除法操作时的行为不同,用户可以根据具体情况选择使用哪种数据类型。但无论使用哪种数据类型,都需要进行测试以了解权衡的具体情况。

0