簡體   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