0. はじめに
.NET標準のConvert.ToString( int value, int toBase )
は
10進数から2, 8, 16進数に変換した文字列を返してくれますが、
個人的に文字列の形式がイマイチな気がするのでピカイチにする拡張メソッドを作りました。
何らかの参考になればと
1. こーしたい
例えば下のようにConvert.ToString()
を使って数値を16進数、2進数に変換すると、
int n = 9999999;
Convert.ToString( n, 16 );
Convert.ToString( n, 2 );
出力は以下になります。
98967f
100110001001011001111111
この出力形式のイヤなところ
・バイトの区切り位置が分からん
・オール0のバイトは文字列に変換してくれない
・パッと見何バイトか分からん
・16進数の場合は小文字なのがなんかイヤ
こうあってほちかった
00 98 96 7F
00000000 10011000 10010110 01111111
2. こーしました
ということで、DIY(てめーでやれ)の精神にのっとり以下の拡張メソッドを作りますた。
using System;
using System.Linq;
namespace MyLibrary.Extensions
{
/// <summary>
/// Int32 拡張メソッドクラス
/// </summary>
public static class Int32Extensions
{
/// <summary>
/// 2進数表記の文字列に変換します。
/// </summary>
/// <param name="value">変換対象の値</param>
/// <returns>16進数表記の文字列(形式:11111111 ... 11111111)</returns>
public static string ToBin( this int value ) => value.ToAnyBase( 2, "11111111".Length );
/// <summary>
/// 16進数表記の文字列に変換します。
/// </summary>
/// <param name="value">変換対象の値</param>
/// <returns>16進数表記の文字列(形式:FF FF FF FF)</returns>
public static string ToHex( this int value ) => value.ToAnyBase( 16, "FF".Length );
/// <summary>
/// 8進数表記の文字列に変換します。
/// </summary>
/// <param name="value"></param>
/// <returns>8進数表記の文字列(形式:037 777 777 777)</returns>
public static string ToOct( this int value ) => value.ToAnyBase( 8, "777".Length );
/// <summary>
/// 10進数の値を、4桁区切りの基数表記の文字列に変換します。
/// </summary>
/// <param name="value">変換対象の値</param>
/// <param name="toBase">変換対象の基数</param>
/// <param name="length">変換対象の基数における、1バイトを表現可能な桁数(例: 16進数 = "FF" = 2 )</param>
/// <returns></returns>
private static string ToAnyBase( this int value, int toBase, int length )
{
var strs = Convert.ToString( value, toBase ).ToUpper()
.PadLeft( length * sizeof( int ), '0' )
.Select( ch => ch.ToString() );
return string.Join( string.Empty, strs.Select( ( s, i ) =>
( i + 1 ) % length == 0 ? s + " " : s ) ).TrimEnd();
}
}
}
中核処理ToAnyBase()
をToHex()
、ToBin()
から呼び出して変換を行っています。
ちょこっと変更すればshort
やlong
にも対応できそうです。
以下のように呼び出して使います。
int n = 9999999;
n.ToHex();
n.ToBin();
すると、冒頭にお見せした個人的ピカイチな文字列を返してくれます!やったぜ。
00 98 96 7F
00000000 10011000 10010110 01111111
3. 他の n 進数にも変換したい
実はToAnyBase()
内で使用しているConvert.ToString()
の仕様で
2、8、10、16進数にしか対応できません。。。。
なので(実用的かどうかは別として)、5進数や7進数に変換したい場合は
別途処理をモニモニ書く必要があります。ゴメンナサイ (´ω`/ )
Convert.ToString()を笑うものはConv(ryに泣く
4.おわりに
今回はちょっとした小ネタを投下させていただきました。
現在アイディア募集中なので、
他にもこんな拡張メソッドが欲しい!いや作れ!などなど
コメントお待ちしておりまーす