31

NSDecimal、NSNumber、NSNumberDecimal、CFNumberについてたくさん読んだことがありますが、それは私にとって一種のジャングルになり始めています。

基本的に、私は次のような単純な計算を処理する単純なモデルクラスを作成しようとしています。

#import <Foundation/Foundation.h>


@interface Test : NSObject
{
    float rate;
    float amount;
    int duration;
}

- (float)capitalizedAmount;

@end

@implementation Test

- (float)capitalizedAmount {
    return (amount*pow((1.0+rate),duration));
}

@end

このような他のクラスをたくさん持つ予定であり、キー値コーディングを行うためのフィールドのリストのみを保持しているため、これらのメソッドとセッターに文字列として名前を付けてアクセスしたいと思います。

// This is just the desired behavior
// This evidently won't work with the previous class definition
Test *obj = [[Test alloc] init];
[NSNumber numberWithInt:10]
...
float r;
r = [obj performSelector:NSSelectorFromString(@"capitalizedAmount")];

これは不可能でperformSelector:あり、オブジェクトを返すため、オブジェクトをcapitalizedAmount返す必要があることを理解しています。NSInvocationcomp.langのObjective-CFAQの内容と関連部分を読みました。

また、使用する必要があることも理解していますNSDecimalNumberが、知りたいことが2つあります。

  1. やや複雑なクラス(UITableViewに表示されるこの種の財務計算のみ)では、メモリのオーバーヘッドとパフォーマンスの低下は許容できますか?私はCのバックグラウンドがあまりありません...
  2. のような機能を使うのは面倒で複雑すぎませんdecimalNumberByAdding:か?__add__Pythonを使用すると、オブジェクトで演算子を使用するように定義するのは簡単でした。からfloat値を取得する必要があります。次に、計算を実行して、 ?NSDecimalNumberでラップされた結果を返します。NSDecimalNumberこの問題にどのように対処しますか?

シンプルで美しい解決策を探しています!

同じ分野でのもう1つの質問:iPhone Core FoundationCFBooleanのオブジェクトラッパーですか?BOOL

ご助力ありがとうございます!

4

3 に答える 3

20

財務計算を行うときに浮動小数点演算エラーを回避するためにNSDecimalまたはNSDecimalNumberを使用する必要があるという点で、Oleは正しいです。ただし、NSDecimalNumberではなく、NSDecimalとそのC関数を使用することをお勧めします。NSDecimalの計算ははるかに高速であり、自動解放されたオブジェクトの作成を回避するため、メモリ使用量が大幅に向上します。

例として、MacBookAirで2つのタイプの数学演算のベンチマークを行いました。

NSDecimal

Additions per second: 3355476.75
Subtractions per second: 3866671.27
Multiplications per second: 3458770.51
Divisions per second: 276242.32

NSDecimalNumber

Additions per second: 676901.32
Subtractions per second: 671474.6
Multiplications per second: 720310.63
Divisions per second: 190249.33

NSDecimalとNSDecimalNumberを使用した場合、パフォーマンスが約5倍向上しなかった操作はディビジョンだけでした。iPhoneでも同様のパフォーマンスの向上が見られます。これは、メモリの節約とともに、最近CorePlotをNSDecimalの使用に切り替えた理由です。

遭遇する唯一の問題は、NSDecimal型に値を出し入れすることです。float値と整数値を直接行き来するには、NSDecimalNumberをブリッジとして使用する必要がある場合があります。また、Core Dataを使用する場合は、値をNSDecimalsではなくNSDecimalNumbersとして保存します。

于 2009-11-10T18:48:09.157 に答える
3

これらのメソッドとセッターに文字列として名前を付けてアクセスしたいのは、このようなクラスを他にもたくさん用意する予定であり、キー値のコーディングを行うためのフィールドのリストのみを保持しているためです。

r = [obj performSelector:NSSelectorFromString(@"capitalizedAmount")];

KVC は、単に文字列を使用してオブジェクトにメッセージを送信するだけではありません。Key-Value コーディング プログラミング ガイドを参照してください。

NSDecimalNumber から float 値を取得し、計算を実行して結果を NSDecimalNumber にラップして返す必要がありますか?

いいえ。10進浮動小数点 ( /NSDecimalNumber) から 2 進浮動小数点 ( / ) への変換には損失がありfloatます。そのようにすると、一部の計算では結果が不正確になります。doubleNSDecimal

于 2009-11-10T04:19:50.983 に答える