【问题标题】:Objective-c mile/km conversionObjective-c 英里/公里转换
【发布时间】:2012-11-24 14:00:34
【问题描述】:

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

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

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

我在 Core-Data 中仅以公里为单位保存距离。我使用 int。所以每次我得到距离时,我都会执行以下操作:

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

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

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

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

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

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

谢谢。

【问题讨论】:

  • 您需要存储的最大距离是多少?我们是在谈论地球上的距离,还是您需要更大的距离?
  • 您可以考虑将您的距离和单位存储在字典中并保存到NSUserDefaults
  • 最大距离999999公里。
  • 不是你的问题,但更简单的方法是让你在启动时设置的某种全局值是 0.621... 或 1.0。那么你就不需要每次都编写“单元”的测试代码了。
  • 每次将乘法或除法的浮点结果转换为 int 时,都会损失大约半公里的精度。您可以通过将内部数字保持为 float/double 并仅在将值存储在 Core Data 中时转换为 int 来将损失减半。但是为什么不想使用浮点数呢?

标签: objective-c nsuserdefaults unit-conversion


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    如果您通过一次转换数字而造成的精度损失是可以接受的,那么我会在每次显示/保存它时停止来回转换,并且只转换,如果需要,当用户输入值时。

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

    - (void)textFieldDidEndEditing:(UITextField *)textField {
        intTotalKM = [textField.text intValue];
    
        if ([unit isEqualToString:@"mile"]) {
            intTotalKM = intTotalKM / 0.621371192;
        }
    }
    

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我个人只会以米为单位存储距离,这应该可以为您提供足够的精度,以便根据需要转换为英里或公里。采取非常简单的方法! +1
      【解决方案4】:

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

      【讨论】:

      • 好吧,他可以妥协并使用浮动。
      • 你是对的。我想知道是否还有其他更适合我的情况的转换方式?
      • 你可以用米代替公里。
      • @Yossarian -- 是的 -- 可以使用我的转换因子方案并将其设置为 1000.0 或 621.37...如果您在 km 和 km 之间来回切换,您仍然会丢失一些东西英里,但如果您坚持使用其中一个或另一个,这些值将精确到一米。
      猜你喜欢
      • 2017-06-12
      • 1970-01-01
      • 2013-07-24
      • 2021-12-17
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多