- PR -

数値が近似値?に変換されてしまいます(Oracle接続)

投稿者投稿内容
hasamarujp
会議室デビュー日: 2006/11/02
投稿数: 3
投稿日時: 2006-11-02 13:16
開発環境
VS2005
Oracle9iR1
ODAC10gR2
開発言語
VB.NET
Windowsアプリケーション

Oracleに
次のような列を持つテーブルを作成しました。

A NUMBER(14,2)
B NUMBER(15,2)
C NUMBER(16,2)
D NUMBER(17,2)

このテーブルに対してデータセットを作成して、
DATAGRIDのデータソースに設定します。

テーブルの各列に、7.02を投入します。
これをDATAGRIDで表示させると、

A 7.0200000000000005
B 7.0200000000000005
C 7.02
D 7.02

と表示されてしまいます。
(ほかには0.83→0.83000000000000007)

データセットの列のデータ型を見ると、

A Double
B Double
C Decimal
D Decimal

データセット上は7.02で問題ありませんが、
DATAGRIDに投入した時点でおかしくなるようです。
(7.02は7時間2分という意味合いで登録していました。)
勝手に変換するなんて...

どうぞよろしくお願いします。
shimix
ぬし
会議室デビュー日: 2004/08/05
投稿数: 512
お住まい・勤務地: 大分市
投稿日時: 2006-11-02 13:20
引用:

hasamarujpさんの書き込み (2006-11-02 13:16) より:
テーブルの各列に、7.02を投入します。
これをDATAGRIDで表示させると、

A 7.0200000000000005
B 7.0200000000000005
C 7.02
D 7.02

と表示されてしまいます。
(ほかには0.83→0.83000000000000007)

データセットの列のデータ型を見ると、

A Double
B Double
C Decimal
D Decimal


Doubleであればこれが一番誤差の少ない値では?少数点以下があるものをDoubleに入れた時点で近似値でしか表せないと思いますが。

列がNUMBERであればデータセットを(C,Dと同様に)Decimalにしてはいけないんですか?

[ メッセージ編集済み 編集者: shimix 編集日時 2006-11-02 13:25 ]
hasamarujp
会議室デビュー日: 2006/11/02
投稿数: 3
投稿日時: 2006-11-02 13:45
引用:

shimixさんの書き込み (2006-11-02 13:20) より:
Doubleであればこれが一番誤差の少ない値では?少数点以下があるものをDoubleに入れた時点で近似値でしか表せないと思いますが。

列がNUMBERであればデータセットを(C,Dと同様に)Decimalにしてはいけないんですか?

[ メッセージ編集済み 編集者: shimix 編集日時 2006-11-02 13:25 ]



7.01や7.03だと問題ありません。
Doubleに変換しているのはODACなのでなんとも...。
データセットの型指定を列個別にする必要があるということでしょうか?
(ODACに任せておいてはダメ?)
私はまだまだ初心者なのですが、
一般の開発者の方はこの仕様をご存知の上で、このような不具合がでないように
留意して開発されているということなのでしょうか?

どうぞよろしくお願いします。
ぷさいくろう
ぬし
会議室デビュー日: 2006/08/30
投稿数: 1034
投稿日時: 2006-11-02 13:46
二進数で0.02を保存するからっしょ
デシマルにしたらん
hasamarujp
会議室デビュー日: 2006/11/02
投稿数: 3
投稿日時: 2006-11-02 14:10
引用:

二進数で0.02を保存するからっしょ
デシマルにしたらん



2進数にした時に循環小数?になる場合に発生する、ということでしょうか?
しかし、0.02だと問題ないです。
(金額をDouble型のフィールドで管理したため、
消費税が狂う、っていうのは知っています。)

ちなみに、
VB.NET上で列TYPEをDoubleにしたデータセットを
作成したところ、7.02もそのまま表示されます。
また、DATAGRID側の列のみをDecimalにした場合、
うまくいきません。

こういう問題が発生する可能性があるのなら、
そもそもODACがきちんとDecimalに変換してくれればいいのに...。
でもデータセット上は7.02に見えるんですが...。
(なんかみなさんのご回答を見ていると、私の不勉強が原因?)
碧流
会議室デビュー日: 2006/11/01
投稿数: 13
投稿日時: 2006-11-02 14:43
Double型とSingle型は基本的に近似値で値を持っています。
見た目上、7.02、0.02、7.01、7.03になっていますが、
メモリ上では近似値になっています。

正しい値をとりたいのであれば、Decimal型をおすすめします。
oracleの方も出来れば、10進型にしたほうがいいと思います。

もしくは、A NUMBER(14,2)→NUMBER()に変更するといいのでは、
ないのでしょうか。
うちは、基本的にNUMBER()やっております。
ぷさいくろう
ぬし
会議室デビュー日: 2006/08/30
投稿数: 1034
投稿日時: 2006-11-02 14:51
引用:

hasamarujpさんの書き込み (2006-11-02 14:10) より:
引用:

二進数で0.02を保存するからっしょ
デシマルにしたらん



2進数にした時に循環小数?になる場合に発生する、ということでしょうか?
しかし、0.02だと問題ないです。
(金額をDouble型のフィールドで管理したため、
消費税が狂う、っていうのは知っています。)

ちなみに、
VB.NET上で列TYPEをDoubleにしたデータセットを
作成したところ、7.02もそのまま表示されます。
また、DATAGRID側の列のみをDecimalにした場合、
うまくいきません。



そりゃ問題のないデータだってあるし
問題のあるデータだってある

0.5とか0.625なら問題ないか試してみたらん
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-11-02 15:00
(Oracle でも .NET でも)
Double や Single はその名のとおり、
単精度の浮動小数点数と倍精度の浮動小数点数なので、
高精度な結果が求められる計算には使用しないほうが良いです。
というより、構造からして無理だし。

で、Oracle のマニュアルを見ると
http://otndnld.oracle.co.jp/document/products/oracle10g/101/doc_v12/win.101/B15519-01/featOraCommand.htm
.NET の Decimal は Oracle では NUMBER になるから、
データベースのほうも NUMBER が良いんじゃないの?ってことになる。
_________________
かるあ のメモスニペット

スキルアップ/キャリアアップ(JOB@IT)