快速旁白:我将使用" Float"引用.Net浮点数和只有7位有效数字的SQL浮点数。我将使用" Double"引用.Net double和带有15位有效数字的SQL float。我也意识到这与其他关于小数/双打的帖子非常相似,但这些帖子的答案确实不一致,我真的想要一些针对我特定情况的建议......
我是一个正在重写旧应用程序的团队的一员。原始应用程序使用浮动(7位数)。这当然引起了问题,因为应用程序进行了大量计算并且非常快速地累积了四舍五入的错误。在某些时候,许多浮动都改为小数。后来,数据库中的浮点数(7)全部变为双打(15)。之后,我们在涉及双精度的计算中又出现了几个错误,并且它们也被改为小数。
今天,我们数据库中所有浮点数的1/3都是小数,其余的是双精度数。我的团队希望"标准化"我们在数据库中的所有浮点数(以及新的.Net代码)只能使用小数或双精度数,除非必须使用另一个。团队的大多数人都使用小数;我是团队中唯一提倡使用双打而不是小数的人。这就是为什么......
我的队友争辩说:
我坚信,由浮点数引起的原始问题只有7位有效数字和简单算术(例如10001 * 10001)导致数据快速消耗掉他们拥有的几个有效数字。我不认为这与二进制浮点数只能近似十进制值有什么关系,我相信使用双精度可以解决这个问题。
我认为双打问题的出现是因为在计算中沿着小数点使用了双精度值,这些值在数据类型之间来回转换。其中许多计算将在计算中的中间步骤之间进行舍入!
我试图说服我的团队不要让阳光下的所有东西变成小数。无论如何,数据库中的大多数值都不会超过5或6位有效数字。不幸的是,我的团队中其他成员的排名太高了,他们的看法却截然不同。
答案 0 :(得分:1)
当您需要完全准确的基数为10的数字(财务数据,成绩)时,请使用decimal
当您存储自然不精确的数据(测量,温度),想要多更快的数学运算时,请使用double
或float
,并且可以牺牲少量的不精确度。
由于您似乎只存储各种测量(无论如何都有一些精度),float
将是合理的选择(如果您需要超过7位数的精度,则为double
)。
使用小数实际上解决了双倍的问题吗?
不是真的 - 数据只会与用于生成数据的测量结果一样准确。你真的可以说测量的数量是123.4567克吗?用于测量的设备是否具有这种精确度?
为了解决“舍入误差”,我认为你无法确切地说1234.5克的测量值是否正好正好中途 - 它可能很容易就是1234.49克,这将会向下舍入反正。
您需要决定的是“可接受的精度水平”,并始终将该精度作为最后一步。不要对数据或中间计算进行舍入。
如果使用双打更合适,我可以提出什么参数(除了我已经提出的参数)可以说服我的团队不要将所有内容都改为小数?
除了转换时间外,你唯一真正牺牲的就是速度。了解速度的唯一方法是尝试两种方式并衡量差异。
答案 1 :(得分:0)
你最好尽量不要失去精确度。我想我的错可能说服你选择加倍。
===>我做了一些错误的算术,它返回了一些非常奇怪的东西:
给定0.60
,它会返回5
int get_index(double value) {
if (value < 0 || value > 1.00)
return -1;
return value / 0.10;
}
我修好了:
int get_index(double value) {
if (value < 0 || value > 1.00)
return -1;
return (value * 100000000) / (0.10 * 100000000);
}