web-dev-qa-db-ja.com

数値を丸める責任があるのはどのレイヤーですか?

私は金融システムを開発していて、金額を四捨五入するための明確なポリシーを持ちたいと思っています。

次のレイヤーがあるとします。

  • 見る
  • API
  • エンティティモデル
  • 持続性

これらのレイヤーを介して金銭的価値を渡し、モデルの計算でそれを使用している場合、どのレイヤー(存在する場合)で「デフォルト」の丸めポリシーを適用する必要がありますか?

数値を丸めることは、日付のフォーマットのような「ビュー」の問題であるため、私の本能はビューにあります。また、エンティティが金額の値を丸めると、計算の精度に影響を与える可能性があるため、問題が発生する可能性があると感じています。ただし、私のAPIで値を「お金」として指定した場合、丸められていない値を消費者に提供するのは正しくないように見えます。 £109.56ではなく£109.563393939939。

これに関する「ベストプラクティス」を見つけることができませんでした。

この古い質問は別として: https://stackoverflow.com/a/3840903/47018

2
James Close

金額の値は一般に浮動小数点(常に近似エラー!)を使用しませんが、JavaではBigDecimal、SQLではDECIMALのように固定小数点を使用します。通貨の場合、定義された精度(たとえば、小数点以下2桁)があります。

現在、国の規制では、精度6(ヨーロッパ)の税金など、一部の計算の精度を規定しています。これらの種類の精度はビジネスロジックの一部である必要があり、計算の正確な値を丸めます。

次に、ビューなどの上位のレイヤーには固定精度が与えられ、計算からの値はすでに丸められています。

このようにして、エクスポートされた値のエンドポイントの合計(システムの外部、エクスポートされたExcelなど)は、システム内の合計からの偏差を与えません。

12
Joop Eggen

2つのレベルの丸めを行う必要があります。主なものは、必要な精度のレベルに丸めるビジネスロジックです。 UIは、表示目的で個別に丸めることができます。これに関するルールは要件の一部である必要があります。それらのいくつかは、さまざまなトランザクションの精度または異なる状況での丸め方を指定する法律から派生している可能性があります。

9
Ryathal

また、エンティティが金額の値を丸めると、計算の精度に影響を与える可能性があるため、問題が発生する可能性があると感じています。ただし、私のAPIで値を「お金」として指定した場合、丸められていない値を消費者に提供するのは正しくないように見えます。 £109.56ではなく£109.563393939939。

これは正しいです。

金融アプリケーションを構築している場合、データを保存するときに正確さを失いたくなる理由はわかりません。途中で丸めが発生することはありません(ただし、ユーザーが入力した小数点以下の桁数を制御することは悪い考えではありません)。

そうは言っても、GBP通貨(または同様の形式の通貨)を使用している場合、ユーザーは小数点以下2桁を表示する必要はありません。このため、私はビューレイヤーのみがデータを丸めることを確認し、従来の「ハーフアップ」丸めに従います。

1
Adam Bates

計算を行うときは、その計算の正確なルールを見つけてください。たとえば、英国でのVATの計算を管理する税法は「興味深い」としましょう。

多くの場合、計算には1つ以上の丸めステップが含まれます。仕様に記載されていないが必須の丸めステップがある場合があります。その場合は、誰かが仕様を更新してください。有用な「デフォルト」のルールがある可能性は低いです。

したがって、すべての計算をそのルールに従って実行し、その後は変更しないでください。計算のルールに従って結果が£105.3743275である場合、それが保存方法です。計算の一部として最後に丸めステップが必要な場合は、それを実行して丸められた値を保存します。

1
gnasher729

その他の回答はありがとうございます。この一般的なポリシーを提案します。

  • 表示-単一のデフォルトの丸めポリシーを表示に適用します
  • API-丸めなし
  • モデル-ビジネス要件で指定されている場合を除き、丸めなし
  • 永続性-ストレージに必要な精度とスケールを決定し、データの格納に単一のデフォルトの丸めポリシーを適用します

要約すると、レイヤーの3つは丸める必要があるかもしれません!

金額に関する特定の状況:GBPシステム、SQL Server、.NET、EntityFramework、Open API(Swagger)REST JSONサービスおよびWebクライアント

  • デフォルトでは、お金はデータベースにDecimal 18、2格納されますが、ビジネス要件でさらにdpsが必要であることが明記されている場合を除きます。
  • ゼロへの中間丸めを使用してデータを保存する際にすべての金額を丸めます
  • ビジネス要件で明確に定義されていない限り、モデルでは丸めは行われません(例:税計算では6 dps)
  • ファサードまたはAPIレイヤーでの丸めなし-したがって、APIは£158.992323232として「金額」の値を返す可能性があります
  • ゼロに向けた中点丸めを使用して、すべての金額の値を2 dpsに丸めます
0
James Close