繁体   English   中英

Coredata和NSDecimalNumber

[英]Coredata and NSDecimalNumber

我在核心数据中存储的十进制数字有问题。 当我将数字0.6789保存到数据库中时,它将另存为0.6788999999999999。

我在某处读过,建议将十进制数列作为十进制数以保持精度,因为核心数据会自动处理核心数据中十进制列的NSDecimalNumber。

下面是我的实体类:

@interface TestEntity : NSManagedObject
@property (nonatomic, retain) NSDecimalNumber * cost;
@end

@implementation TestEntity
@dynamic cost;
@end

这就是我插入数据的方式:

TestEntity *envelope = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:self.managedObjectContext];
envelope.cost = [NSDecimalNumber decimalNumberWithString:@"0.6789"];
[self.managedObjectContext save:nil];

请有人帮我,插入数据库后如何处理十进制数字及其精度?

核心数据由SQLite支持。 根据SQLite文档, SQLite仅支持64位 IEEE 754格式(Objective C中为double )的最大64位整数和浮点数。 因此,精度仅限于这些类型,整数的有效位数约为18.75,浮点数的有效位数约为15.75。

通常,对于大多数应用程序来说, doubleint64_t是正确的,但要求精度超过15-18个有效数字的应用程序除外。 在某些辖区中,银行机构必须根据法律高精度地存储小数,并且为此使用特殊类型。

如果您的应用程序是标准的,我将使用int64_tdouble 如果使用NSDecimalNumber它将由SQLite引擎存储为64位类型(浮点数或整数取决于小数部分的存在)。 这意味着您的精度将限制为15到18位数字。

如果由于NSDecimalNumber的高精度算法而要使用它,则仍将其限制为NSDecimalNumber位数字,但是如果动态范围可以表示为15/18位数字(带小数部分),则不会引入舍入误差。或没有)。

如果您的动态范围更大,则NSDecimalNumber提供38位数字。 为了将其存储在由Coreite支持SQLite的持久性存储中并能够保持38位数字,您应该将其来回转换为字符串,以便将其作为字符串存储在Core Data中。 您可以在NSManagedObject的子类上创建一个类别,该类别具有几种方法来存储(编码)和检索(解码)数字为字符串。 模型中的基础属性应该是字符串,而不是数字。

NSDecimalNumber有两种方法-stringValue-stringValue -initWithString:为您执行转换。 您只需要构造两个在自定义类别中依赖它们的方法。

综上所述:

  • 如果需要十进制数字,请为15个有效数字使用double
  • 如果不需要十进制数字,请使用int64_t表示18个有效数字
  • 如果您需要高精度的十进制数字,请使用NSDecimalNumber表示38个有效数字(转换为字符串以存储在CoreData中)

作为CoreData后端的SQLite不支持小数,而是使用float。


从SQLite文档中:

向SQLite 3数据库中的每一列分配以下类型关联性之一:TEXT NUMERIC INTEGER REAL BLOB

有关更多详细信息,请参见SQLite文档https://sqlite.org/datatype3.html 3.1.1。 相似性名称示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM