我试图使用java在我的SQLite3数据库中存储一个浮点数。当我在数据库中存储数字1.2时,它实际存储为1.199999998&每个偶数(1.4,1.6等)都会出现相同的情况。
这使得删除行真的很困难,因为我根据其版本列(其类型= float)删除了一行。所以这条线不会工作: “DELETE FROM tbl WHERE version = 1.2”
多数民众赞成因为没有1.2而只有1.19999998。当我在SQLite3数据库中存储一个浮点数时,如何确保它是我输入的确切数字?
答案 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标准
实现答案 4 :(得分:1)
正如Joel Coehoorn指出的那样,1.2是二进制的重复分数1.0011 0011 0011 ...并且不能用有限的位来精确表示。
IEEE 754 float
最接近的是1.2000000476837158203125。使用double
得到的最接近的是1.1999999999999999555910790149937383830547332763671875。我不知道你从哪里获得1.199999998。
浮点设计用于表示近似数量:物理测量(游泳池永远 1.2米深),或非理性值函数,如{{1 },sqrt
或log
。如果您需要一个精确到15位有效数字的值,它可以正常工作。如果你真的需要一个完全值,那就不那么重要了。
对于版本号,更合适的表示形式是一对整数:一个用于主要版本,一个用于次要版本。这也可以正确处理序列1.0,1.1,...,1.9,1.10,1.11,它们会在sin
列中排序错误。