【发布时间】:2010-12-23 18:27:21
【问题描述】:
滑块是我的应用程序的主要用户交互元素(看图...)。我使用它们记录百分比值,然后将其作为Readings 存储在我的核心数据存储中。根据百分比值的性质,我会将它们存储为 0 到 1 之间的十进制值,并将滑块设置为从 0 到 1 的范围,并连续触发它们的值更改动作。当我需要显示它们时,我从数据存储中获取它们并将它们显示为典型的百分比值,例如67%.
现在要注意了:UISlider 的 value 属性是 float 类型。这意味着我会从一开始就遇到舍入错误。我非常注重准确性,所以我希望在整个应用程序中处理它们时尽可能地减少误差范围。
有哪些选项可用于管理我从滑块中读取的百分比值、存储在 Core Data 中并显示在我的应用程序的其余部分中?或者更好的是,就代码可维护性、内存使用/性能和准确性而言,我提出的这些选项中的哪一个最适合我的应用获得的值有多少?
-
使用原始浮点数或双精度数
实际上这是BAD,显然是因为舍入错误。甚至 0.64 也会在某个时间点变成 0.63(我已经用我的滑块进行了测试,这些都出现了很多)。差异可能高达 0.01,我的应用程序绝对不能容忍这一点。为什么我还要写这个作为一个选项?
-
将滑块范围设置为 0 到 100 之间,读取它们,向上/向下舍入并存储为整数
这是一个有趣的选择,因为我只会将值显示为
##%而不是0.##。我也不需要对这些值进行算术运算,所以这样做看起来没问题:// Recording and storing // Slider range is 0 to 100 int percentage = (int) floor(slider.value); // Or ceil() [reading setValue:[NSNumber numberWithInt:percentage]]; // Value is an integer // Displaying NSNumber *val = reading.value; [readingLabel setText:[NSString stringWithFormat:@"%d%%", [val intValue]]];当我第一次从滑块上读取它们时,这不会完全消除舍入误差(它们仍然是
floats!),但我认为floor()或ceil()应该消除它。不过,我并不完全确定;也许这里有人可以提供更多见解,这就是我提出这个问题的重点。 -
转换并存储为
NSDecimalNumber对象我查看了
NSDecimalNumber类——毕竟百分比是基数为 10 的因子——但鉴于它产生不可变对象,我不太确定我是否喜欢编写长方法调用的想法重复我的代码并在各处创建大量自动释放的对象。即使是用原语创建
NSDecimalNumbers 也是一种痛苦。目前我只能想到这样做:// Recording and storing // Slider range is 0 to 1 NSDecimalNumber *decimalValue = [NSDecimalNumber decimalNumberWithString: [NSString stringWithFormat:@"%0.2f", slider.value]]; [reading setValue:decimalValue]; // Value is a decimal number将它们乘以 100,因为我将它们显示为
##%(就像我上面所说的那样)也变得非常乏味并创建不必要的额外对象,然后将其转换为NSStrings。我会继续说下去,但我可能会把这篇文章变成咆哮,这绝对不是我想要的。话虽如此,语义上
NSDecimalNumber应该是最有意义的,因为正如我上面所说,我相信百分比应该存储为 0 到 1 之间的十进制值。但是,看看我的应用如何处理百分比值,我不知道是选择将它们乘以 100 并存储为整数还是使用NSDecimalNumber。
您可能会看到我已经稍微倾向于第二个选项(x100,使用整数),因为它更方便并且看起来性能稍好一些。但是,我想看看是否有人认为第三个更好(更多的未来证明?)。
顺便说一句,我不介意修改我的数据模型以更改我的Reading 实体中value 属性的数据类型,并修改我现有的代码以适应这些更改。我还没有做太多,因为我把剩下的时间都花在了担心这件事上。
您认为我应该选择以上哪个选项?
【问题讨论】:
-
NSDecimalNumber继承自NSNumber。您不需要将浮点数转换为字符串,只需执行[NSDecimalNumber numberWithFloat: slider.value]; -
@JeremyP:这是一个公平的观点。
标签: iphone objective-c ios core-data floating-point