SQLite3数据库中的1.2实际上是1.199999998

时间:2011-02-25 03:08:11

标签: sql sqlite floating-point

我试图使用java在我的SQLite3数据库中存储一个浮点数。当我在数据库中存储数字1.2时,它实际存储为1.199999998&每个偶数(1.4,1.6等)都会出现相同的情况。

这使得删除行真的很困难,因为我根据其版本列(其类型= float)删除了一行。所以这条线不会工作: “DELETE FROM tbl WHERE version = 1.2”

多数民众赞成因为没有1.2而只有1.19999998。当我在SQLite3数据库中存储一个浮点数时,如何确保它是我输入的确切数字?

5 个答案:

答案 0 :(得分:3)

如果您需要精确的准确度,请不要使用浮子。请尝试使用小数。

答案 1 :(得分:2)

请记住,您在源代码中输入的1.2或用户输入文本框并最终以数据库结尾的实际存储为二进制值(通常采用称为IEEE754的格式)。要理解为什么这是一个问题,尝试手动将1.2(1 1/5)转换为二进制(二进制.1是1/2,。01是1/4),看看你最终得到了什么:

  

1.001100110011001100110011001100110011

您可以使用this converter来节省时间(忽略在网站上打破周期的最后一个“1”,因为转换器必须绕过最后一位数字。)

如您所见,这是一种重复模式。这种情况几乎永远存在。这就像试图将1/3表示为小数。为了解决这个问题,大多数编程语言都有一个十进制类型(而不是float或double),它保留了一个基数10表示。但是,使用此类型进行的计算速度要慢几个数量级,因此它通常保留用于金融交易等。

答案 2 :(得分:1)

这是浮点数的本质。他们不准确。 我建议您使用整数或文本字段来存储版本。

答案 3 :(得分:1)

你永远不应该依赖浮动或双精度。浮点数永远不应该用于数据库中的键或代表金钱。

在这种情况下你应该使用小数。

浮点数不是准确的数据类型。它们设计得速度快,值范围广,内存占用少。

它们通常使用IEEE标准

实现

http://en.wikipedia.org/wiki/IEEE_754-2008

答案 4 :(得分:1)

正如Joel Coehoorn指出的那样,1.2是二进制的重复分数1.0011 0011 0011 ...并且不能用有限的位来精确表示。

IEEE 754 float最接近的是1.2000000476837158203125。使用double得到的最接近的是1.1999999999999999555910790149937383830547332763671875。我不知道你从哪里获得1.199999998。

浮点设计用于表示近似数量:物理测量(游泳池永远 1.2米深),或非理性值函数,如{{1 },sqrtlog。如果您需要一个精确到15位有效数字的值,它可以正常工作。如果你真的需要一个完全值,那就不那么重要了。

对于版本号,更合适的表示形式是一对整数:一个用于主要版本,一个用于次要版本。这也可以正确处理序列1.0,1.1,...,1.9,1.10,1.11,它们会在sin列中排序错误。