アフィリエイト広告を利用しています

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

2018年05月05日

【012】Decimal型


Decimal型

 浮動小数点型である Single(C# では float)型や Double(C# では double)型の場合は、演算が2進数で行われることに起因する誤差により、期待する結果が得られない場合があります。
 例えば、
   Double a1 = 0.1;
   Double a2 = 0;
   for (var i = 0; i < 10; i++)
     a2 += 0.01;
   Console.WriteLine(a1 == a2);

では、True を期待しますが、結果は False となります。

 このような不都合を避けるための手段の一つに、Decimal(C# では decimal)型の利用があります。
 ※Decimal型は、内部的に10進数演算を行うことにより、2進数と10進数の相互変換の際の丸め誤差を防いでいます。

 Decimal 型は、Double型より有効桁数が多い(ただし、扱うことのできる値の範囲はDouble型より狭い)ので、財務・金融などの計算に利用されています。

 実数値リテラルを Decimal として扱うには、サフィックス m または M を用います。
ただし、整数型は暗黙裏に decimal に変換されるのでサフィックスは不要です。
   Decimal b1 = 0.1m;
   Decimal b2 = 0;


 また、Decimal型と、Double型・Single型の間では暗黙裏の型変換が行われないので、型変換には明示的なキャストが必要です。
   Desimal x = 1.23456m;
   Double y = (Double)x;
   Desimal z = (Decimal)y;


 下記のプログラムでは、同じ計算を Double型と Decimal型で行った場合の結果が異なっています。
Decimal型での計算で、期待される結果が得られていることを確認できます。


using System;

namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
// Double型
Double a1 = 0.1;
Double a2 = 0;
for (var i = 0; i < 10; i++)
a2 += 0.01;
Console.WriteLine(a1 == a2); // False

// Decimal型
Decimal b1 = 0.1m;
Decimal b2 = 0;
for (var i = 0; i < 10; i++)
b2 += 0.01m;
Console.WriteLine(b1 == b2); // True
}
}
}



【011】文字列型(2)


 文字列型(2)

 StringBuilder型のオブジェクトから String型の文字列を得るには、ToStringメソッドを利用します。
   StringBuilder stb = new StringBuilder("あいうえお");
   String str = stb.ToString();

 
 StringBuilder型や Object型は、値型ではなく参照型ですから、「 == 」演算子による比較では参照先の比較が行われます。
 ただし、前回《010》も確認しましたが、String型文字列の場合、参照型であるにもかかわらず、「 == 」演算子は、値を比較します。

 下記のプログラムにおいて、
   String str1 = "abc";
   String str2 = "abc";

として作成した文字列は値が等しい(@)だけでなく、参照先も等しいことがわかります(C,E)。
したがって、少なくとも私の使っている処理系では、同じ値の文字列リテラルを同一とみなし、
記憶域上に格納した1つの文字列リテラルを共有しているようです。

   StringBuilder stb1 = new StringBuilder("abc");
   StringBuilder stb2 = new StringBuilder("abc");

stb1, stb2 は StringBuilder型ですから、「 == 」演算子による比較の結果は False です(A)。

   String str3 = stb1.ToString();
   String str4 = stb2.ToString();

str3, str4 は、共に"abc"ですから、「 == 」演算子での比較結果は当然 True になります(B)。
 一方、ReferenceEqualsメソッドで str3, str4 を比較すると、結果は False です(D)。
このことから、StringBuilder型オブジェクトから ToStringメソッドで得られたString型文字列 str3, str4 の場合は、同じ値であっても、別々に記憶域上に格納されていることがわかります。


using System;
using System.Text;

namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
String str1 = "abc";
String str2 = "abc";

StringBuilder stb1 = new StringBuilder("abc");
StringBuilder stb2 = new StringBuilder("abc");

String str3 = stb1.ToString();
String str4 = stb2.ToString();

Console.WriteLine(str1 == str2); // @ True
Console.WriteLine(stb1 == stb2); // A False
Console.WriteLine(str3 == str4); // B True

Console.WriteLine(ReferenceEquals(str1, str2));
// C True
Console.WriteLine(ReferenceEquals(str3, str4));
// D False

Console.WriteLine((Object)str1 == (Object)str2);
// E True
}
}
}



ファン
検索
<< 2018年05月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
最新記事
写真ギャラリー
最新コメント
タグクラウド
カテゴリーアーカイブ
月別アーカイブ
プロフィール
×

この広告は30日以上新しい記事の更新がないブログに表示されております。