保存

时间:2016-07-23 06:11:17

标签: python django floating-point decimal latitude-longitude

我想在Place模型中保存纬度和经度。 我尝试了两个字段,floatfield和decimalfield。

1。 FloatField模型

class Place1(models.Model):
    latitude = models.FloatField()
    longitude = models.FloatField()

2。 DecimalField模型

class Place2(models.Model):
    latitude = models.DecimalField(max_digits=18, decimal_places=16)
    longitude = models.DecimalField(max_digits=19, decimal_places=16)

两个字段都在以下值上运作良好。

  

10.1
10.12
10.123
10.1234
...
10.1234567890123

但是,在第16个数字(不是'十六个小数位')之后,保存时它会无意中舍入

place1 = Place1.objects.create(
            latitude=10.123456789012345,
            longitude=100.123456789012345
         )

>>place1.latitude
10.123456789012345 # works well

>>place1.longitude
100.123456789012345 # works well

# Unintentionally rounded when I get object from db. 
>>Place.objects.last().latitude
10.12345678901235 # unintentionally rounded

>>Place.objects.last().longitude
100.1234567890123 # unintentionally rounded



place2 = Place2.objects.create(
        latitude=Decimal('10.123456789012345'),
        longitude=Decimal('100.123456789012345')
     )

>>place2.latitude
Decimal('10.1234567890123450') # works well

>>place2.longitude
Decimal('100.1234567890123450') # works well

# Unintentionally rounded when I get object from db. 
>>Place.objects.last().latitude
Decimal('10.1234567890123500') # unintentionally rounded

>>Place.objects.last().longitude
Decimal('100.1234567890123000') # unintentionally rounded

我无法找到关于此无意识轮次的任何解释。在django文件中。请帮忙。感谢。

1 个答案:

答案 0 :(得分:1)

你不能在django docs中找到'无意的舍入',因为django不是这里的罪魁祸首。

当您的列数据类型为Float时,它会执行舍入的MYSQL。

  

为了获得最大的可移植性,需要存储近似数值数据值的代码应使用 FLOAT DOUBLE PRECISION ,不能指定精度或位数。

     

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

但是对于值的准确性,您应该使用 DecimalField

你说你使用过 DecimalField ,但这些数字仍在四舍五入。这可能会发生,因为您的表格列仍然是 Float 类型,而不是十进制

将表格列类型更改为十进制,您可以看到更改。

示例SQL语法ALTER TABLE your_table MODIFY latitude decimal(m,n);,OR

如果您使用的是MYSQL Workbench或任何UI界面,请直接从列信息标签中更改它(它们有一个)

  

DECIMAL和NUMERIC类型存储精确的数值数据值。在保持精确精度

非常重要时使用这些类型      

在DECIMAL列声明中,可以(通常是)指定精度和比例;例如:纬度DECIMAL(m,n)

     

精度(m)表示为值存储的有效位数,而(n)表示可以存储的位数小数点。

在这里为您的田地纬度和经度所需的精确比例提供帮助

有关十进制数据类型的详细信息,请参阅here;有关您遇到的问题的信息,请参阅here