何时使用浮点数与小数


14

我正在构建此API,并且数据库将存储代表以下之一的值:

  • 百分比
  • 平均

老实说,我不知道如何表示范围介于0到100%之间的数字。应该是

  • 0.00-1.00
  • 0.00-100.00
  • 我不知道的任何其他选择

有一个明确的选择吗?一种在数据库上表示从0%到100%的东西的全局方式?更进一步,它的正确类型是float还是小数?

谢谢。



5
数字可以以多种方式存储。使用0-100或0-1存储百分比没有本质上的错误。重要的是您需要对数字做些什么,需要什么精度等等。您必须先解释更多的上下文,然后才能给出正确的答案。您是否需要存储可以用少量小数位数精确表示的数字?如果将事情平均,您将获得三分之二或七分之一的分数。您需要完全存储吗?还是大概?大概多少?您将如何处理他们?
埃里克·波斯特皮希尔

1
如果值是0.00到100.00,以0.01为步长,则10001个不同的值。只需使用一个int代表百分之一或单位Permyriad或‱。
chux-恢复莫妮卡

@ chux-ReinstateMonica-是的,“缩放的整数”是可能的,但是笨拙。
瑞克·詹姆斯

@RickJames也许。我还没有发现缩放整数很困难。
chux-恢复莫妮卡

Answers:


4

我会采取相反的立场。

FLOAT用于近似数字,例如百分比,平均值等。在显示值时应进行格式化,无论是使用应用程序代码还是使用FORMAT()MySQL函数。

永远不要测试float_value = 1.3; 失败的原因有很多。

DECIMAL应该用于货币值。 DECIMAL当值需要四舍五入为美元/美分/欧元/等时,避免第二次四舍五入。会计师不喜欢零头。

MySQL的实现DECIMAL允许65个有效数字;FLOAT给出大约7和DOUBLE大约16。对于传感器和科学计算,通常7绰绰有余。

至于“百分比”-有时我TINYINT UNSIGNED只想占用1个字节的存储空间而又不需要太多精度时就使用过;有时我用过FLOAT(4个字节)。没有专门针对百分比调整的数据类型。(另请注意,它DECIMAL(2,0)不能保存该值100,因此从技术上讲,您将需要此值DECIMAL(3,0)。)

或者有时我使用的a FLOAT的值在0到1之间。但是在显示“百分比”之前,我需要确保乘以100。

更多

这三个“百分比,平均值,比率”气味都像浮游物一样,所以这将是我的首选。

决定数据类型的一种标准...将存在多少个值副本?

如果您有一个带有一行列的十亿行表,请考虑这TINYINT将占用1个字节(总计1GB),但FLOAT要占用4个字节(总计4GB)。OTOH,大多数应用程序没有那么多行,因此这可能无关紧要。

作为“一般”规则,“精确”值应使用INT或的某种形式DECIMAL。不精确的事物(科学计算,平方根,除法等)应使用FLOAT(或DOUBLE)。

此外,输出的格式通常应留给应用程序前端。也就是说,即使“平均值”可以计算为“ 14.6666666 ...”,显示屏也应该显示类似“ 14.7”的内容。这对人类更友好。同时,您具有基础值,以后可以确定“ 15”或“ 14.667”是首选的输出格式。

范围“ 0.00-100.00”既可以FLOAT 使用输出格式设置,也可以使用输出格式设置,也可以使用DECIMAL(5,2)(3字节)预先确定,您将始终希望得到所指示的精度


3

我通常建议您不要使用float。浮点数确实表示以2为底的数字,这会导致某些(精确)数字在运算或比较中被四舍五入,因为它们无法准确地存储在以2为底的数字中。这可能会导致令人惊讶的行为。

考虑以下示例

create table t (num float);
insert into t values(1.3);

select * from t;

| num |
| --: |
| 1.3 |

select * from t where num = 1.3;

| num |
| --: |

基数为2的数字比较1.3失败。这很棘手。

相比之下,十进制可精确表示范围内的有限数。如果在上面的示例中更改floatdecimal(2, 1),则可以得到预期的结果。


4
在几个方面,这个答案是错误的。“相比之下,十进制的范围较小,但可以精确表示该范围内的有限数字”,这是错误的:十进制不能精确表示⅓。“一些(精确的,有限的)数字是四舍五入的”是不正确的;数字不是“四舍五入”。转换和其他操作可能会四舍五入。默认的舍入模式最通常为将最近的关系舍入为偶数,而不是向上舍入。
埃里克·波斯特皮希尔

4
精度问题不是由于“浮点数”,而仅仅是由于数字表示:所有有限的数字表示都具有有限的精度:浮点,定点,整数,有理数,十进制,二进制,所有东西。
埃里克·波斯特皮希尔

2
叹。你修好了什么?我的评论说答案是错误的,因为它说十进制提供了其范围内数字的精确表示,但实际上并不是因为它没有提供⅓的精确表示。更改说的是“准确”,而不是“精确”,但是为什么二进制浮点数不那么好?对于⅓来说都不是精确的,而对于浮点数既不精确,又取决于您的准确阈值和精确度他们有。该问题表明将代表平均值,对三件事求平均值可得出⅓之类的数字。
埃里克·波斯特皮希尔

4
评论说,最接近的关系是到最接近的关系,但是答案仍然是向上取整。答案说比较可能会四舍五入,但是比较是完美的:比较总是返回数学上正确的结果,没有四舍五入。(某些编程语言可能会在比较之前转换操作数,但这些操作是单独的操作。)
Eric Postpischil

1
1/3不能以二进制或十进制精确表示。要获得$ 14.99的20%折扣,就不要求四舍五入。
瑞克·詹姆斯

0

浮点数和小数点之间的差是精度。十进制可以100%精确地表示十进制格式精度内的任何数字,而Float不能精确地表示所有数字。

使用十进制表示例如财务相关值,使用浮点表示例如图形相关值


0

decimal(5,2)如果要以与存储它相同的方式存储它,我建议使用,因为这decimal是为了保留精确的精度。(请参阅https://dev.mysql.com/doc/refman/8.0/zh-CN/fixed-point-types.html

由于浮点值是近似值而不是作为精确值存储的,因此在比较中尝试将它们视为精确值可能会导致问题。它们还受平台或实现依赖性的约束。

https://dev.mysql.com/doc/refman/8.0/en/floating-point-types.html

SQL语句中编写的浮点值可能与内部表示的值不同。

对于DECIMAL列,MySQL执行的精度为65个十进制数字,这应该可以解决最常见的不准确性问题。

https://dev.mysql.com/doc/refman/8.0/zh-CN/problems-with-float.html


0

小数: 对于金融应用程序,最好使用小数类型,因为它可以为您提供较高的准确性,并且易于避免舍入错误

Double: Double类型可能是用于实值的最常用数据类型,除了处理资金外。

Float: 它主要用于图形库中,因为对处理能力的要求非常高,还使用了可能会舍入错误的情况。

参考:http : //net-informations.com/q/faq/float.html


0
mysql> create table numbers (a decimal(10,2), b float);
mysql> insert into numbers values (100, 100);
mysql> select @a := (a/3), @b := (b/3), @a * 3, @b * 3 from numbers \G

*********************************************************************

@a := (a/3): 33.333333333
@b := (b/3): 33.333333333333
@a + @a + @a: 99.999999999000000000000000000000
@b + @b + @b: 100

十进制完全符合这种情况下的预期,截断了其余部分,从而丢失了1/3的部分。

因此,对于总和,小数点更好,但是对于除数,浮点数更好,当然可以达到一定程度。我的意思是,使用DECIMAL不会以任何方式为您提供“防故障算法”。

我希望这将有所帮助。


0

在tsql中:Float,0.0存储为0,不需要在小数点后定义数字,例如,您不需要编写Float(4,2)。小数,将0.0存储为0.0,它具有定义为小数(4,2)的选项,我建议使用0.00-1.00,通过这样做,您可以计算该百分比的值而无需乘以100,并且如果报告然后设置数据类型该列的百分比与MS Excel和其他平台视图一样0.5 -> 50%

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.