タイトル : Re^2: 数字の比較について 投稿日 : 2017/01/19(Thu) 21:22 投稿者 : 魔界の仮面弁士
> > If K = 2.3 Then > > 型は大きい方に丸められますので、結果として > If K = CSng(2.3R) Then 'これは True > ではなく、 > If CDbl(K) = 2.3R Then 'これは False > として比較されます。 上記の部分について、もう少し具体的に書いてみます。 まず、浮動小数点数の内部表現を見てみましょう。 Dim b1() As Byte = BitConverter.GetBytes(2.3) Dim K As Single = 2.3 Dim b2() As Byte = BitConverter.GetBytes(K) b1 は Double のバイナリなので 8 バイトです。 b2 は Single のバイナリなので 4 バイトです。 b1 のバイナリは 16進数で 66-66-66-66-66-66-02-40 です。 これは 2 進小数「10.010011001100110011001100110011001100110011001100110」を表しており、 10進数では『2.2999999999999998223643160599749535322189331054687500』にあたります。 一方、b2 のバイナリは 16進数で 33-33-13-40 です。 これは 2 進小数「10.0100110011001100110011」を表しており、 10進数では『2.29999995231628417968750』にあたります。 もしも > If K = CSng(2.3R) Then が行われていたとしたらどうなるでしょう。 右辺の CSng(2.3R) においては、2.3R すなわち、 『2.2999999999999998223643160599749535322189331054687500』 という値が、Single の精度に【縮小変換】されることになります。 この変換処理により、右辺は 33-33-13-40 のバイナリ、 すなわち『2.29999995231628417968750』になります。 左辺値も『2.29999995231628417968750』なので、同値として扱われます。 しかし実際には、 > If CDbl(K) = 2.3R Then に相当する処理が行われていました。 左辺の CDbl(K) により、『2.29999995231628417968750』が【拡大変換】で Double になりますが、 この結果は 00-00-00-60-66-66-02-40 のバイナリとなります。 これは、「10.010011001100110011001100000000000000000000000000000」な 2 進小数を意味しており、 10進小数『2.2999999523162841796875000000000000000000000000000000』に相当する数値です。 右辺値は「10.010011001100110011001100110011001100110011001100110」な 2 進小数、 すなわち『2.2999999999999998223643160599749535322189331054687500』な値なのですから、 両者は不一致とみなされるわけですね。 |