Bol*_*ock 4 iphone floating-point core-data objective-c ios
滑块是我的应用程序的主要用户交互元素(如图...).我用它们来记录百分比值,然后将其作为Readings 存储在我的Core Data存储中.根据百分比值的性质,我将它们存储为0到1之间的十进制值,并将滑块设置为0到1的范围,并连续触发它们的值更改操作.当我需要显示它们时,我从数据存储中获取它们并将它们显示为典型的百分比值,例如67%.
现在这里是捕获:类型的value属性.这意味着我将从一开始就遇到舍入错误.我对准确性很坚定,所以当我在整个应用程序中处理它们时,我希望尽可能地减少误差范围.UISliderfloat
有哪些选项可用于管理我从滑块读取的百分比值,存储在Core Data中并显示在我的应用程序的其余部分?或者更好的是,在代码可维护性,内存使用/性能和获得的值的准确性方面,我提出的哪些选项最适合我的应用程序?
使用原始浮动或双打
实际上这很糟糕,显然是因为舍入错误.甚至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]]];
Run Code Online (Sandbox Code Playgroud)
当我第一次从滑块上读出它们时,它不会完全消除舍入错误(它们仍然float是s!),但是floor()或者ceil()应该将它切掉,我想.我不完全确定; 也许这里有人可以提供更多的见解,这就是我提出这个问题的重点.
转换为NSDecimalNumber对象并存储为对象
我看过这个NSDecimalNumber类 - 百分比毕竟是基数为10的因素 - 但是考虑到它产生了不可变对象,我不太确定我喜欢在我的代码中反复编写长方法调用并创建一个到处都是自我释放物体的陨石.
NSDecimalNumber即使用原始语言创建s也是一种痛苦.目前我只能想到这样做:
// 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
Run Code Online (Sandbox Code Playgroud)
将它们乘以100,因为我将它们显示为##%(就像我上面说的那样)也变得非常繁琐,并创建了不必要的额外对象,然后将其转换为NSStrings.我会继续,但我可能会把这篇文章变成一个咆哮,这绝对不是我想要的.
说到这一点,语义NSDecimalNumber应该是最有意义的,因为,正如我上面所说,我认为百分比意味着存储为0到1之间的十进制值.但是,看看我的应用程序如何使用百分比值,我不知道是否选择将它们乘以100并存储为整数或使用NSDecimalNumber.
您可能会看到我已经略微倾向于第二个选项(x100,使用整数),因为它更方便,并且看起来性能略好一些.但是,我想看看是否有人认为第三个是更好的(更多的未来证明?).
顺便说一句,我不介意修改我的数据模型以更改实体中value属性的数据类型Reading,并修改现有代码以适应更改.我还没有做太多,因为我花了其余的时间来担心这件事.
您认为我应该选择以上哪个选项?
如果你需要做的就是从滑块中读取,保存值并显示它们,处理来自缩放的圆形浮动滑块输入的原始整数将是我推荐的.无论如何,滑块并不是所有精确的输入方法,因此您的用户不会注意到舍入与滑块头的像素位置是否完全匹配.
我在这里使用与您在确定计算中有效数字的数量时相同的推理,该计算将实际数据作为输入(如温度读数等).如果您的输入源仅具有两位数的精度,则将计算报告为四位有效数字是没有意义的.
如果要对十进制值执行更多扩展计算,但希望避免浮点错误,则需要NSDecimals和NSDecimalNumbers.例如,我在我的应用程序中运行高精度计算时使用它们,或者我需要以某种方式操纵货币.在这两个中,出于性能原因我坚持使用NSDecimal,在我需要与Core Data交互或需要将数值导入NSDecimal结构时使用NSDecimalNumber.
在这种情况下,似乎NSDecimal会过度杀伤,因为你并没有真正调整滑块值,只是在屏幕上显示它们.如果你确实需要执行以后的操作(减少一半,运行公式等),我建议将滑块四舍五入为整数表示,从中创建NSDecimal结构,以NSDecimals执行计算,然后使用NSDecimal/NSDecimalNumber的字符串输出例程,用于在屏幕上显示结果.然后,您可以轻松地将计算值保存为Core Data中的NSDecimalNumber,或者作为SQLite或其他文件中的字符串表示形式.
此外,我不会太担心像这样的简单计算的性能,直到像仪器这样的东西告诉你它们是一个热点.可能性很大,这些用NSDecimal等计算不会.