C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 金額の扱いについて


(過去ログ 16 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■6149 / inTopicNo.1)  金額の扱いについて
  
□投稿者/ むねお (1回)-(2007/08/02(Thu) 14:08:45)

分類:[VB.NET/VB2005] 

VB.NETやC#.NETなどで金額を扱うアプリケーションを作成する場合に定石等はあるでしょうか?
(個別の技法を含めたトータル的な手法などです。)
例えば、Decimal型の小数点位置を予め決定して、それをカスタムデータ型で用意するとか、
どこそこの配布ライブラリを使用するとかそういう感じです。
一般的な手法がなければ、こうしているといった類のものでもよいのでご教示頂けないでしょうか。
よろしくお願いします。
引用返信 編集キー/
■6155 / inTopicNo.2)  Re[1]: 金額の扱いについて
□投稿者/ よねKEN (64回)-(2007/08/02(Thu) 15:26:05)
よねKEN さんの Web サイト
> VB.NETやC#.NETなどで金額を扱うアプリケーションを作成する場合に定石等はあるでしょうか?

Decimal型を使うというくらいで、他には特にないと思います。

> 一般的な手法がなければ、こうしているといった類のものでもよいのでご教示頂けないでしょうか。

何かで詰まっているのでしょうか?あるいは、何かを懸念されているのでしょうか?
その辺がわからないと漠然としていて何とコメントしてよいのか困ってしまいます。

引用返信 編集キー/
■6157 / inTopicNo.3)  Re[2]: 金額の扱いについて
□投稿者/ むねお (2回)-(2007/08/02(Thu) 16:30:05)
> 何かで詰まっているのでしょうか?あるいは、何かを懸念されているのでしょうか?
> その辺がわからないと漠然としていて何とコメントしてよいのか困ってしまいます。

書き方が悪くすいません。
具体的に何かに詰まっているということはありません。懸念ということであれば、金額を
計算したりする場合の丸めの問題や誤差の問題をグループ開発を行う場合に各プログラマ
におまかせではバグが点在するのではないか、とご指摘のように漠然と考えています。
(この心配自体が無用でしょうか?)
例えばSQLServerで金額フィールドがDECIMAL(10,2)(有効桁数が10で、小数点以下桁数が2であるDECIMAL)
という定義の場合、プログラムでデータを読み込んで扱う場合にやはりそのままDECIMAL(10,2)
で扱いたいと思っています。そのことを各プログラマが意識しないで済むような手法というか、
そういうのが面倒だから○○のライブラリを買っている、とかいうのでもあればと思い投稿しました。

よねKUNさんとしましては、規約?などでDecimal型を使うという事にして、表示等必要な際に
カスタム書式指定文字列などで規定の表示書式で表示する、ということでよいのでしょうか。


引用返信 編集キー/
■6159 / inTopicNo.4)  Re[3]: 金額の扱いについて
□投稿者/ よねKEN (65回)-(2007/08/02(Thu) 17:34:03)
よねKEN さんの Web サイト
> 具体的に何かに詰まっているということはありません。懸念ということであれば、金額を
> 計算したりする場合の丸めの問題や誤差の問題をグループ開発を行う場合に各プログラマ
> におまかせではバグが点在するのではないか、とご指摘のように漠然と考えています。

私なら、
・丸め方(切捨て、切上げ、四捨五入、銀行型丸め)や誤差の扱いについて仕様書に明記する
・コードレビューできちんとフォローする。もちろんテスト項目についてもその点を考慮した項目を入れる。
・理解が不足しているメンバーがいるならレクチャーする
ということをすることで対応します。
プログラマが根本的に理解していないようでは、やはりバグが生まれると思うからです。

> 例えばSQLServerで金額フィールドがDECIMAL(10,2)(有効桁数が10で、小数点以下桁数が2であるDECIMAL)
> という定義の場合、プログラムでデータを読み込んで扱う場合にやはりそのままDECIMAL(10,2)
> で扱いたいと思っています。そのことを各プログラマが意識しないで済むような手法というか、

SQLServerから出し入れするときに小数部2桁で扱うということですよね?
プログラム内部では小数部3桁以上を持つことになると思います。(でないと丸め方を選べない)

> そういうのが面倒だから○○のライブラリを買っている、とかいうのでもあればと思い投稿しました。

丸めや誤差という観点では特に何のライブラリも使っていません。

> よねKUNさんとしましては、規約?などでDecimal型を使うという事にして、表示等必要な際に
> カスタム書式指定文字列などで規定の表示書式で表示する、ということでよいのでしょうか。

適切な桁数で適切な丸め方を適用してから、希望の表示方法で表示ですね。
XXXの丸め方をやるときは、YYYクラスのZZZメソッドをこう使うこととか、
丸め方の方法も明確にしておけばある程度安全かと思います。

引用返信 編集キー/
■6173 / inTopicNo.5)  Re[4]: 金額の扱いについて
□投稿者/ むねお (3回)-(2007/08/03(Fri) 10:51:40)
> プログラマが根本的に理解していないようでは、やはりバグが生まれると思うからです。
至極もっともなご意見で恐れ入ります。私自身.NETでの開発経験がないのでメンバーにレクチャー
できるかどうか自信がないのでなんとか手法で逃げようとしていたのかも知れません。

> SQLServerから出し入れするときに小数部2桁で扱うということですよね?
> プログラム内部では小数部3桁以上を持つことになると思います。(でないと丸め方を選べない)

最初は下記のようにSQL Serverの結果と一致するように固定小数点型をエミュレート?するような
ものを考えていたのですが、何か方向性が違うような気がしていた次第です。


-----------------------------------------------------------------------------------
Option Strict On

Imports System.Data.SqlTypes

Public Class Class1

    Shared Sub main()

        Dim d As Decimal = 1D
        Dim d2 As Decimal = d / 3D
        Dim d3 As Decimal = d2 * 3D
        Dim d4 As Decimal = (1D / 3D) * 3D

        MessageBox.Show(d3.ToString & ":" & d4.ToString)

        Dim c As New Currency(19, 4)
        Dim c2 As New Currency(19, 4)
        Dim c3 As New Currency(19, 4)
        Dim c4 As New Currency(19, 4)

        c.Value = 1D
        c2.Value = c.Value / 3D
        c3.Value = c2.Value * 3D
        c4.Value = (1D / 3D) * 3D

        MessageBox.Show(c3.Value.ToString & ":" & c4.Value.ToString)

    End Sub

End Class

Public Structure Currency

    Private _Value As SqlDecimal
    Private _Presition As Integer
    Private _Scale As Integer

    Public Sub New(ByVal p As Integer, ByVal s As Integer)
        _Presition = p
        _Scale = s
    End Sub

    Public Property Value() As SqlDecimal
        Get
            Return _Value
        End Get
        Set(ByVal sd As SqlDecimal)
            _Value = SqlDecimal.ConvertToPrecScale(sd, _Presition, _Scale)
        End Set
    End Property

End Structure

-----------------------------------------------------------------------------------

【SQL Server】

declare @d decimal(19,4) 
declare @d2 decimal(19,4) 
declare @d3 decimal(19,4) 
declare @d4 decimal(19,4)

set @d = 1.
set @d2 = @d / 3.
set @d3 = @d2 * 3.
set @d4 = (1. / 3.) * 3.

select str(@d3,19,4) + ':' + str(@d4,19,4)

結果:0.9999:1.0000


引用返信 編集キー/
■6174 / inTopicNo.6)  Re[5]: 金額の扱いについて
□投稿者/ まどか (352回)-(2007/08/03(Fri) 11:15:27)
> > プログラマが根本的に理解していないようでは、やはりバグが生まれると思うからです。
> 至極もっともなご意見で恐れ入ります。私自身.NETでの開発経験がないのでメンバーにレクチャー
> できるかどうか自信がないのでなんとか手法で逃げようとしていたのかも知れません。

「金額」という点では軽く考えないほうがいいです。
金融などのシステムではどんなに小さな誤差でも会社、顧客などのすべての人と組織に致命傷を与えます。
そういう意味では、いわゆる基準・標準化というのはおこなうべきですし、
関係者にその意識が無いのは逆に大問題です。

意識せずに満たされる手法等があればそれに越したことはありませんが
それに関わらず、徹底的にシビアなテストをおこなう必要があるでしょう。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -