タグ : テスト

 

.NET 文字列を指定されたバイト数に切り詰める

VBのLeftBやRightBに相当するメソッドを作成しました。
 
以前に投稿した「SubstringByteメソッド」を使用しますので、切り詰めた部分文字列が文字化けする場合は、文字化けした文字を除去します。
 
●左から切り詰める場合
StringUtility utility = new StringUtility();

utility.TruncateByteLeft("1あいうえお", 4);
実行結果:”1あ”
 
●右から切り詰める場合
StringUtility utility = new StringUtility();

utility.TruncateByteRight("1あいうえお", 4);
実行結果:”えお”
 
以下のエリアではTruncateByteLeftメソッドとTruncateByteRightメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility();

utility.TruncateByteLeft(
    
 ", 
 );
実行結果:
“”
 
StringUtility utility = new StringUtility();

utility.TruncateByteRight(
    
 ", 
 );
実行結果:
“”
 
※実行結果の半角スペースは「¸」で表します。
 
TruncateByteLeftメソッド、TruncateByteRightメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字列を指定されたバイト長に左側から切り詰めます
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に切り詰めた文字列</returns>
        /// <remarks>
        /// <para>文字列が指定されたバイト長に満たない場合は、成型せずに返します</para>
        /// <para>切り詰めた文字列の末尾に全角文字途中の要素が混入している場合は除去します</para>
        /// </remarks>
        public string TruncateByteLeft(string target, int lengthByte)
        {
            // 対象の文字列のバイト長が指定されたバイト長以下の場合
            if (GetByteCount(target) <= lengthByte)
            {
                return target;
            }

            return SubstringByte(target, 0, lengthByte);
        }

        /// <summary>
        /// 文字列を指定されたバイト長に右側から切り詰めます
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="lengthByte">バイト長</param>
        /// <returns>指定されたバイト長に切り詰めた文字列</returns>
        /// <remarks>
        /// <para>文字列が指定されたバイト長に満たない場合は、成型せずに返します</para>
        /// <para>切り詰めた文字列の先頭に全角文字途中の要素が混入している場合は除去します</para>
        /// </remarks>
        public string TruncateByteRight(string target, int lengthByte)
        {
            // 対象の文字列のバイト長を取得
            int targetByteCount = GetByteCount(target);

            // 対象の文字列のバイト長が指定されたバイト長以下の場合
            if (targetByteCount <= lengthByte)
            {
                return target;
            }

            return SubstringByte(target, targetByteCount - lengthByte, lengthByte);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
 

.NET 文字列からバイト単位で部分文字列を取得する

C#、VB.NETで半角を1バイト、全角を2バイトとして、指定したバイト数の部分文字列を取得する、SubstringByteメソッドを作成しました。
 
SubstringByteメソッドに「対象の文字列」、「開始位置のバイト(0から始まるインデックス)」、「部分文字列のバイト数」を指定し実行すると部分文字列を取得できます。
 
StringUtility utility = new StringUtility();

utility.SubstringByte("1あいうえお", 2, 6);
実行結果:”いう”
 
上記のように指定すると「あ」の後ろ半分から「え」の前半分までの6バイトの部分文字列を対象とし、文字化けする最初と最後の文字を除去した「いう」を返します。
 
半角を1バイト、全角を2バイトは文字エンコーディングに「シフトJIS」を指定した場合ですが、「.NET 文字列のバイト数を取得する」と同様に他の文字エンコーディングにも対応しております。
 
以下のエリアではSubstringByteメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility();

utility.SubstringByte(
    
 ", 
 , 
 );
実行結果:
“”
 
※実行結果の半角スペースは「¸」で表します。
 
SubstringByteメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        private Encoding _myEncoding = Encoding.GetEncoding("Shift_JIS");

        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        public Encoding MyEncoding
        {
            get
            {
                return this._myEncoding;
            }
        }

        /// <summary>
        /// 文字列からバイト単位で部分文字列を取得します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <param name="lengthByte">部分文字列のバイト数</param>
        /// <returns>文字列からバイト単位で取得した部分文字列</returns>
        public string SubstringByte(string target, int startIndexByte, int lengthByte)
        {
            if (startIndexByte < 0)
            {
                throw new ArgumentOutOfRangeException(
                    "開始位置インデックスバイトが0未満です。");
            }

            if (lengthByte < 0)
            {
                throw new ArgumentOutOfRangeException(
                    "部分文字列のバイト数が0未満です。");
            }

            // 対象の文字列をバイト配列にする
            byte[] targetBytes = MyEncoding.GetBytes(target);

            // 開始位置インデックスバイト+部分文字列のバイト数が文字列のバイト数を超える場合
            if (targetBytes.Length < startIndexByte + lengthByte)
            {
                throw new ArgumentOutOfRangeException("開始位置インデックスバイトまたは部分文字列のバイト数の指定に誤りがあります。");
            }

            // 対象の文字列からバイト単位で部分文字列を取得
            string partialString = MyEncoding.GetString(
                targetBytes, startIndexByte, lengthByte);

            // 先頭に全角文字途中の要素が混入している場合は除去
            partialString = TrimHeadHalfwayDoubleByteCharacter(
                partialString, target, targetBytes, startIndexByte);

            // 末尾に全角文字途中の要素が混入している場合は除去
            partialString = TrimEndHalfwayDoubleByteCharacter(
                partialString, target, targetBytes, startIndexByte, lengthByte);

            return partialString;
        }

        /// <summary>
        /// 先頭に全角文字途中の要素が混入している場合は除去します
        /// </summary>
        /// <param name="partialString">部分文字列</param>
        /// <param name="target">対象の文字列</param>
        /// <param name="targetBytes">対象の文字列のバイト配列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <returns>先頭の全角文字途中の要素を除去した部分文字列</returns>
        private string TrimHeadHalfwayDoubleByteCharacter(
            string partialString, string target, byte[] targetBytes, int startIndexByte)
        {
            // 部分文字列が空の場合
            if (partialString == string.Empty)
            {
                return partialString;
            }

            // 開始位置の要素を含む部分文字列を取得
            string leftString = MyEncoding.GetString(targetBytes, 0, startIndexByte + 1);

            // 部分文字列の先頭要素が一致する場合
            if (target[leftString.Length - 1] == partialString[0])
            {
                return partialString;
            }

            // 先頭の全角文字途中の要素を除去
            return partialString.Substring(1);
        }

        /// <summary>
        /// 末尾に全角文字途中の要素が混入している場合は除去します
        /// </summary>
        /// <param name="partialString">部分文字列</param>
        /// <param name="target">対象の文字列</param>
        /// <param name="targetBytes">対象の文字列のバイト配列</param>
        /// <param name="startIndexByte">開始位置インデックスバイト</param>
        /// <param name="lengthByte">部分文字列のバイト数</param>
        /// <returns>末尾の全角文字途中の要素を除去した部分文字列</returns>
        private string TrimEndHalfwayDoubleByteCharacter(
            string partialString, string target, byte[] targetBytes, int startIndexByte,
            int lengthByte)
        {
            // 部分文字列が空の場合
            if (partialString == string.Empty)
            {
                return partialString;
            }

            // 最終要素を含む部分文字列を取得
            string leftString = MyEncoding.GetString(
                targetBytes, 0, startIndexByte + lengthByte);

            // 部分文字列の最終要素が一致する場合
            if (target[leftString.Length - 1] == partialString[partialString.Length - 1])
            {
                return partialString;
            }

            // 末尾の全角文字途中の要素を除去
            return partialString.Substring(0, partialString.Length - 1);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
 

.NET 文字列のバイト数を取得する

C#、VB.NETで半角を1バイト、全角を2バイトとして、文字列のバイト数を取得するGetByteCountメソッドを作成しました。
 
StringUtility utility = new StringUtility();

utility.GetByteCount("1あいうえお");
実行結果:11
 
半角を1バイト、全角を2バイトは文字エンコーディングに「シフトJIS」を指定した場合ですが、もちろん他の文字エンコーディングにも対応しております。
 
たとえば全ての文字を2バイトで表すUnicodeを指定した場合は、
 
StringUtility utility = new StringUtility(Encoding.Unicode);

utility.GetByteCount("1あいうえお");
実行結果:12
 
となります。
 
以下のエリアではGetByteCountメソッドを実際に動かした時の挙動を確認できます。
 
StringUtility utility = new StringUtility(
    
Encoding.GetEncoding(
 "));
 
utility.GetByteCount(
 ");
実行結果:
 
 
GetByteCountメソッドのソースコードは以下になります。
 
        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        private Encoding _myEncoding = Encoding.GetEncoding("Shift_JIS");

        /// <summary>
        /// 文字エンコーディング
        /// </summary>
        public Encoding MyEncoding
        {
            get
            {
                return this._myEncoding;
            }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public StringUtility()
        {
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="encoding">文字エンコーディング</param>
        public StringUtility(Encoding encoding)
        {
            this._myEncoding = encoding;
        }

        /// <summary>
        /// 文字列のバイト数を取得します
        /// </summary>
        /// <param name="target">対象の文字列</param>
        /// <returns>文字列のバイト数</returns>
        public int GetByteCount(string target)
        {
            return MyEncoding.GetByteCount(target);
        }
 
 
Clipボタンをクリックすると、「StringUtility」というクラスがコピーされます。このソースを「StringUtility.cs」ファイルにコピーするとすぐご利用いただけます。
 

.NET 整数を切り上げる

C#、VB.NETで整数を切り上げる場合も、「.NET 小数点以下を切り上げる」で作成したRoundUpメソッドが利用できます。
 
        /// <summary>
        /// 値の小数部を切り上げ、指定の桁数に丸めます
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimals">小数部桁数</param>
        /// <returns>丸められた値</returns>
        private double RoundUp(double value, int decimals)
        {
            // 小数部桁数の10の累乗を取得
            double pow = Math.Pow(10, decimals);

            return 0 <= value ? Math.Ceiling(value * pow) / pow :
                Math.Floor(value * pow) / pow;
        }
 
 
このページでは、上記RoundUpメソッドを実際に動かした時の挙動を確認できます。
 
小数部桁数に「-3」を指定すると100の位を切り上げます。「1400」⇒「2000」という動きになり、ExcelのROUNDUPメソッドと同じ動作をします。もちろん通常通り小数点以下を切り上げることもできます。
 
RoundUp( 
 , 
 ); 
実行結果:
 
 

.NET 整数を切り捨てる

C#、VB.NETで整数を切り捨てる場合も、「.NET 小数点以下を切り捨てる」で作成したTruncateメソッドが利用できます。
 
        /// <summary>
        /// 値の小数部を切り捨て、指定の桁数に丸めます
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimals">小数部桁数</param>
        /// <returns>丸められた値</returns>
        private double Truncate(double value, int decimals)
        {
            // 小数部桁数の10の累乗を取得
            double pow = Math.Pow(10, decimals);

            return 0 <= value ? Math.Floor(value * pow) / pow :
                Math.Ceiling(value * pow) / pow;
        }
 
 
このページでは、上記Truncateメソッドを実際に動かした時の挙動を確認できます。
 
小数部桁数に「-3」を指定すると100の位を切り捨てます。「1500」⇒「1000」という動きになり、ExcelのROUNDDOWNメソッドと同じ動作をします。もちろん通常通り小数点以下を切り捨てることもできます。
 
Truncate( 
 , 
 ); 
実行結果:
 
 

.NET 整数を四捨五入する

C#、VB.NETで整数を四捨五入する場合は、「Math.Round」メソッドを使ってメソッドを自作する必要があります。
 
        /// <summary>
        /// 値を四捨五入します
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimals">小数部桁数</param>
        /// <param name="mode">丸める方法</param>
        /// <returns>丸められた値</returns>
        private double Round(double value, int decimals,
            MidpointRounding mode)
        {
            // 小数部桁数の10の累乗を取得
            double pow = Math.Pow(10, decimals);

            return Math.Round(value * pow, mode) / pow;
        }
 
 
このページでは、上記Roundメソッドを実際に動かした時の挙動を確認できます。
 
小数部桁数に「-3」を指定すると100の位を四捨五入します。「1500」⇒「2000」という動きになり、ExcelのRoundメソッドと同じ動作をします。もちろん通常通り小数点以下を四捨五入することもできます。
 
Round( 
 , 
 , 
 ); 
実行結果:
 
 

.NET 小数点以下を切り上げる

C#、VB.NETで小数点以下を切り上げる場合は「Math.Floor」と「Math.Ceiling」メソッドを組み合わせ、用途に合わせてメソッドを自作する必要があります。
 
        /// <summary>
        /// 値の小数部を切り上げ、指定の桁数に丸めます
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimals">小数部桁数</param>
        /// <returns>丸められた値</returns>
        private double RoundUp(double value, int decimals)
        {
            // 小数部桁数の10の累乗を取得
            double pow = Math.Pow(10, decimals);

            return 0 <= value ? Math.Ceiling(value * pow) / pow :
                Math.Floor(value * pow) / pow;
        }
 
 
上記RoundUpメソッドは、符号を無視して絶対値を切り上げる(常に正負の無限大へ近づく)丸めになります。
 
このページでは、上記RoundUpメソッドを実際に動かした時の挙動を確認できます。
 
値と、小数点以下の桁数を入力し実行ボタンをクリックすると、小数部を指定された桁数に成型した値を実行結果に表示します(小数点第二位までに成型したい場合は小数部桁数へ「2」を指定します)。
 
RoundUp( 
 , 
 ); 
実行結果:
 
 
以下にRoundUpメソッドの挙動をまとめました。「試す」ボタンをクリックすると、書式を入力エリアにコピーしますので、実際の動きを確認することができます。

●書式一覧

内容 書式 結果 試す
100.234を小数点第二位までに成型(小数点第三位を切り上げ) Truncate(100.234, 2); 100.24
-100.234を小数点第二位までに成型(小数点第三位を切り上げ) Truncate(-100.234, 2); -100.24
 

.NET 小数点以下を切り捨てる

C#、VB.NETで小数点以下を切り捨てる場合は、「Math.Floor」と「Math.Ceiling」メソッドを組み合わせ、用途に合わせてメソッドを自作する必要があります。
 
        /// <summary>
        /// 値の小数部を切り捨て、指定の桁数に丸めます
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimals">小数部桁数</param>
        /// <returns>丸められた値</returns>
        private double Truncate(double value, int decimals)
        {
            // 小数部桁数の10の累乗を取得
            double pow = Math.Pow(10, decimals);

            return 0 <= value ? Math.Floor(value * pow) / pow :
                Math.Ceiling(value * pow) / pow;
        }
 
 
上記Truncateメソッドは、符号を無視して絶対値を切り捨てる(常に0へ近づく)丸めになります。
 
このページでは、上記Truncateメソッドを実際に動かした時の挙動を確認できます。
 
値と、小数点以下の桁数を入力し実行ボタンをクリックすると、小数部を指定された桁数に成型した値を実行結果に表示します(小数点第二位までに成型したい場合は小数部桁数へ「2」を指定します)。
 
Truncate( 
 , 
 ); 
実行結果:
 
 
以下にTruncateメソッドの挙動をまとめました。「試す」ボタンをクリックすると、書式を入力エリアにコピーしますので、実際の動きを確認することができます。

●書式一覧

内容 書式 結果 試す
100.345を小数点第二位までに成型(小数点第三位を切り捨て) Truncate(100.345, 2); 100.34
-100.345を小数点第二位までに成型(小数点第三位を切り捨て) Truncate(-100.345, 2); -100.34
 

.NET 小数点以下を四捨五入する

C#、VB.NETで小数点以下を四捨五入する場合は「Math.Round」メソッドを使いますが、通常の四捨五入と異なる動きをする場合があります。
 
論より証拠。以下の値に「2.5」を入力し実行ボタンをクリックすると、実行結果に「2.0」と表示されます。
 
Math.Round( 
 ); 
実行結果:
 
 
これは「最近接偶数への丸め」や「銀行家の丸め」と呼ばれ、端数が「0.5」のときに結果が偶数になるような丸め方をするためです。
 
なぜこのような複雑な仕様なのでしょうか?
 
通常の四捨五入の場合、切り捨てられる端数が「1、2、3、4」の4個なのに対し、切り上げられる端数が「5、6、7、8、9」の5個と切り上げられる確率のほうが高いため、丸めた値をたくさん足すと誤差が大きくなってしまいます。
 
そこで「0.5」を常に偶数になるように丸めると、「1.5」が「2.0」、「2.5」が「2.0」と切り上げと切り捨てが等しい確率で発生するため、丸めた値をたくさん足した場合も誤差が少なくなるのです。
 
IEEE 754でも定められている通り、浮動小数点数の丸め方としては通常の四捨五入よりも一般的ではあるのですが、私は普通の四捨五入がしたいんです!
 
その場合は「Math.Round」メソッドの引数に「MidpointRounding.AwayFromZero」を指定します。
 
Math.Round( 
 , 
 );
実行結果:
 
 
Math.Round」メソッドの引数に「MidpointRounding.AwayFromZero」を指定すると「2.5」を「3.0」へ四捨五入してくれます。「銀行家の丸め」をしたい場合は「MidpointRounding.ToEven」を指定します。
 
もちろん小数部を指定の桁数で四捨五入することも可能です。
 
Math.Round( 
 , 
 , 
 ); 
実行結果:
 
 

JavaScript 正規表現の動作確認(リテラルフォーマット)

JavaScriptで正規表現による検索を行った時の挙動を確認できます。
 
正規表現のパターンとフラグ、検索対象を入力し実行ボタンをクリックすると、パターンにマッチした個所を黄色でハイライト表示します。
 
正規表現パターン:
var re = / 
 / 
 
検索対象:

g h T
 6,456 Total Views