1

在我的 iPhone 应用程序中,用户可以在首选项中更改单位(公里或英里)。

[[NSUserDefaults standardUserDefaults] setObject:@"km" forKey:@"distanceUnit"];

或者

[[NSUserDefaults standardUserDefaults] setObject:@"mile" forKey:@"distanceUnit"];

我在核心数据中仅以公里为单位保存距离。我与int一起工作。所以每次我得到距离时,我都会执行以下操作:

if ([unit isEqualToString:@"km"]) {
} else {
    intTotalKM = intTotalKM * 0.621371192;
} 

在节省距离时,我执行以下操作:

if ([unit isEqualToString:@"km"]) {
} else {
    intTotalKM = intTotalKM / 0.621371192;
}

例如,在不改变距离的情况下,当我保存并获取它时,我会损失 1 或 2 公里/英里。

由于0.621371192和我只使用int ,我失去了精度。我不想使用双精度值。您对如何处理这个问题有任何想法吗?

编辑:我想知道是否还有其他更适合我情况的转换方式。

谢谢。

4

4 回答 4

3

唯一无损的解决方案是以原始单位存储距离。添加一个单字符列,指定表示距离的单位,并存储一个代码(例如,'K'英里km'M'英里)以及实际距离。

如果添加列不是一个选项,您可以将单位放在您存储的数字的高位:由于您的应用程序中的最大距离是2^20,您可以使用数字的剩余 12 位来编码单位表示距离。用于dist & 0xFFFFF提取实际距离,并dist >> 20提取单位代码(1for km0for mi)。

于 2012-11-24T14:28:33.273 回答
2

如果您真的希望使用整数并保持精度,请使用较小的单位。如果您的最大要求为 999999km,那么如果您的整数是 32 位的,您可以以米为单位存储值并调整转换以产生码。如果您的整数是 64 位的,那么您可以使用 cm 甚至 mm,但您可能不需要走那么远。这就是一些财务计算的完成方式,例如 1.59 美元不是存储为 1.59 而是存储为 159。

于 2012-11-24T18:20:46.000 回答
2

如果通过一次转换数字而导致的精度损失是可以接受的,那么我会在每次显示/保存它时停止来回转换,并且仅在用户输入值时才转换(如果需要) .

所以换句话说,就像你的用户默认值一样,只有内存中的值代表 km。

- (void)textFieldDidEndEditing:(UITextField *)textField {
    intTotalKM = [textField.text intValue];

    if ([unit isEqualToString:@"mile"]) {
        intTotalKM = intTotalKM / 0.621371192;
    }
}

请注意,此转换在用户输入新值时进行一次。

要向用户显示该值,您可以根据需要将该值转换为英里。保存该值时,您只需保存 intTotalKM 而不进行任何转换,因为它始终存储在 KM 中。

否则,您应该以不会有这种精度损失的方式存储该值。通过存储数字的小数部分(使用双精度数),另存为不同的单位(如米 - 我个人最喜欢的)或存储单位并使用本机值,所有这些都在此处的其他答案中建议。

于 2012-11-26T22:58:09.147 回答
1

你自己已经回答了这个问题:你失去了精度,因为你使用的是整数......你没有太多的选择。要么更改为 double,要么坚持使用 int 和不准确的值...

于 2012-11-24T14:04:01.860 回答