Oracleデータベースには、タイプNUMBER(NULL、精度が指定されていない)の列VALUE_NUMBERを持つテーブル(たとえばMYTABLE)があります。このテーブルには値が含まれています1178.2
標準のADO.Net(実際にはODP.Net)を使用してこの列からデータを取得し、10進値を文字列に変換すると、「1178.20」が返されます。明らかに、定数1178.2M
を文字列に変換すると、出力は。になります1178.2
。
さらに深く掘り下げて、decimal.GetBits()の出力を調べました。これは、両方の数値を比較すると実際には等しいと見なされますが、異なることが判明しました。
以下のコードサンプルは、動作を示しています。
using (var connection = new OracleConnection("my connection string"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "SELECT VALUE_NUMBER FROM MYTABLE";
command.CommandType = CommandType.Text;
using (command)
{
var reader = command.ExecuteReader(CommandBehavior.Default);
reader.Read();
decimal oracleDecimal = reader.GetDecimal(reader.GetOrdinal("VALUE_NUMBER"));
Console.WriteLine(oracleDecimal); // output: 1178.20 (NOT expected)
var bitsFromOracle = decimal.GetBits(oracleDecimal).Select(x => x.ToString());
var bitsFromOracleString = string.Join(",", bitsFromOracle.ToArray());
Console.WriteLine(bitsFromOracleString); // 117820,0,0,131072
// sanity check
const decimal constantDecimal = 1178.2M;
Console.WriteLine(constantDecimal); // output: 1178.2 (expected)
var bitsFromConstant = decimal.GetBits(constantDecimal).Select(x => x.ToString());
var bitsFromConstantString = string.Join(",", bitsFromConstant.ToArray());
Console.WriteLine(bitsFromConstantString); // 11782,0,0,65536
Console.WriteLine(oracleDecimal == constantDecimal); // True
}
}
これはどのように説明されるべきですか?
これを機能させるためのテーブルCREATE&INSERTスクリプトは次のとおりです。
CREATE TABLE MYTABLE (
ID NUMBER(10) NOT NULL,
VALUE_NUMBER NUMBER
);
INSERT INTO MYTABLE(ID,VALUE_NUMBER) VALUES(1,1178.2);
アップデート:
@Vashによる回答とその後のコメントにより、.Net 10進数タイプには、同等性とは無関係であっても、実際にはその桁数に関する情報が含まれているという正しい結論に至りました。このため、ビット表現が異なりますが、メソッドと1178.2M
演算子はこれらの数値を等しいと見なします。1178.20M
.Equals()
==