[英]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。
通常,对于大多数应用程序来说, double
或int64_t
是正确的,但要求精度超过15-18个有效数字的应用程序除外。 在某些辖区中,银行机构必须根据法律高精度地存储小数,并且为此使用特殊类型。
如果您的应用程序是标准的,我将使用int64_t
或double
。 如果使用NSDecimalNumber
它将由SQLite引擎存储为64位类型(浮点数或整数取决于小数部分的存在)。 这意味着您的精度将限制为15到18位数字。
如果由于NSDecimalNumber
的高精度算法而要使用它,则仍将其限制为NSDecimalNumber
位数字,但是如果动态范围可以表示为15/18位数字(带小数部分),则不会引入舍入误差。或没有)。
如果您的动态范围更大,则NSDecimalNumber
提供38位数字。 为了将其存储在由Coreite支持SQLite的持久性存储中并能够保持38位数字,您应该将其来回转换为字符串,以便将其作为字符串存储在Core Data中。 您可以在NSManagedObject
的子类上创建一个类别,该类别具有几种方法来存储(编码)和检索(解码)数字为字符串。 模型中的基础属性应该是字符串,而不是数字。
NSDecimalNumber
有两种方法-stringValue
和-stringValue
-initWithString:
为您执行转换。 您只需要构造两个在自定义类别中依赖它们的方法。
综上所述:
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.