我目前正在创建一个应用程序,允许用户输入重量并选择他们喜欢的单位(公斤和磅之间)。截至目前,数据库是用 Django 编写的,并将特定日期的每个用户体重条目存储为具有 2 位小数精度的字符串,例如,
weight_kg = models.DecimalField(max_digits=5, decimal_places=2, validators=[MinValueValidator(1)])
我面临的问题是在单位之间更改时丢失数据。例如,如果用户选择 165,以
lbs
为单位,我会将其存储在我的数据库中为 74.84
。当关闭并重新打开页面时,它将获取数据并尝试恢复它。这样做,它会将 74.84kg
更改为 164.99lbs
。数据丢失,因为我们不知道用户是否选择了 164.99lbs
还是舍入错误。
我开始认为我选择将权重存储为字符串是一个错误,但是,使用数字时也会出现同样的问题。比如,
let kg_to_lbs = 2.20462;
let lbs_to_kg = 0.453592;
((165 * lbs_to_kg) * kg_to_lbs) // 164.99....
他们有防止此类问题的最佳实践吗?
其他信息,
kg
中,客户端负责将其转换回用于显示的单位并转换为kg
,然后发送到服务器存储。您面临的问题是浮点运算中的常见问题,由于计算机存储和处理数字的方式,浮点运算很难准确处理。出现这个问题是因为公斤和磅之间的转换涉及到非整数比率,无法精确表示为浮点数。
处理这个问题的最佳方法是完全避免浮点运算,而是使用定点表示。在这种情况下,您可以将重量存储为整数克(因为 1kg = 1000g),然后在向用户显示该值时转换为千克或磅。
以下是如何在 Django 模型中实现此功能的示例:
蟒蛇
weight_g = models.IntegerField(validators=[MinValueValidator(1)])
def get_weight_kg(self):
return self.weight_g / 1000
def get_weight_lbs(self):
return self.weight_g * 0.00220462
JavaScript
let kg_to_g = 1000;
let lbs_to_g = 453.592;
let user_weight_kg = 165;
let user_weight_lbs = user_weight_kg * kg_to_g / lbs_to_g;
let stored_weight_g = Math.round(user_weight_kg * kg_to_g);
let restored_weight_kg = stored_weight_g / kg_to_g;
let restored_weight_lbs = stored_weight_g / lbs_to_g;
通过使用整数和舍入,可以确保存储和恢复的值尽可能准确,并避免使用浮点数时出现的数据丢失。