【雑記】 巨大な数字をインクリメントする@C# [パソコン]
私は職業がプログラマで、たまに趣味でプログラミングしたりします。
といっても思いつきでサックリ作るくらいですが。
開発環境はVisual Studio 2008などの高級なものではありません。
・csc
・sakura
・PowerShell
が開発環境です。
つまり、パワシェでCUIリッチなコンソールを開きつつ
サクラエディタで編集してCSCコマンドからコンパイルします。
パワシェはTabキーで補完が利きますしLSコマンドや
CDコマンドがデフォルトで通用するので便利です。
でも、ディレクトリパスを展開するとシングルクォートで囲みたがるのが難点です。
まぁ、Windowsだとディレクトリ名にスペースを入れれるので仕方ないのですが。
つか、Linuxライクな環境に慣れているとファイル名やディレクトリ名に
半角スペースを入れるなんて違和感ありすぎて信じられませんが。
今回はふっと思いついて数字をインクリメントするプログラムを書きました。
ソースコードを書いて実行してテストしましたが、うまくいきました。
少しでもプログラミングの経験がある人なら
「数字をインクリメントして返す」
というプログラムなんて簡単だと思うかもしれません。
端的に書けば、
return int + 1;
で終わりますからね。
でも、私が書いたプログラムは一味違います。
上記のプログラムではint幅、もしくは大きくてもlong幅以上の整数を
+1して返すことは出来ません。
オーバーフローになりますから。
その欠点を克服し、long幅を超えた整数でも+1して
返すことが出来るプログラムを考えました。
public class Incrementor
{
public string number = null;
public void execute()
{
number = "0" + number;
int[] digits = new int[number.Length];
for( int i = 0; i < digits.Length; i++)
{
digits[i] = Convert.ToInt32(number[i] - 48);
}
digits = recursive(digits, digits.Length - 1);
number = string.Empty;
for( int i = 0; i < digits.Length; i++)
{
number += digits[i];
}
number = number.TrimStart(new char[] {'0'});
}
private int[] recursive(int[] digits, int index)
{
digits[index]++;
if (digits[index] == 10)
{
digits[index] = 0;
return recursive(digits,index - 1);
}
else
{
return digits;
}
}
public static void Main(string[] args)
{
Incrementor incrementor = new Incrementor();
incrementor.number = args[0];
incrementor.execute();
Console.Write("answer : ");
Console.WriteLine(incrementor.number);
}
}
PS C:\Lunamaria> C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc -nologo test.cs
PS C:\Lunamaria> .\test 21474839999
answer : 21474840000
PS C:\Lunamaria> .\test 99999999998
answer : 99999999999
PS C:\Lunamaria> .\test 99999999999
answer : 100000000000
といっても、純粋な整数型ではなく文字列型なので使える場面は限られます。
例えばデータベースでTEXT型の主キーカラムを持つテーブルがあったとして
そのカラムにシーケンシャルな数字を入れていくときなどです。
多分、bigint以上のレコードを格納できるはずです。
なにげに単純なループではなくオシャレに再帰で回しています。
どーすか?
これ、どーすか!?
HTML上でソースコードを書くとインデントがうまくいかないのが不便です。
たまにインデントにこだわる人がいて、
・タブインデント
・全角スペースインデント
・半角スペースインデント
が混ざると半ギレになる人もいますね。
といっても思いつきでサックリ作るくらいですが。
開発環境はVisual Studio 2008などの高級なものではありません。
・csc
・sakura
・PowerShell
が開発環境です。
つまり、パワシェでCUIリッチなコンソールを開きつつ
サクラエディタで編集してCSCコマンドからコンパイルします。
パワシェはTabキーで補完が利きますしLSコマンドや
CDコマンドがデフォルトで通用するので便利です。
でも、ディレクトリパスを展開するとシングルクォートで囲みたがるのが難点です。
まぁ、Windowsだとディレクトリ名にスペースを入れれるので仕方ないのですが。
つか、Linuxライクな環境に慣れているとファイル名やディレクトリ名に
半角スペースを入れるなんて違和感ありすぎて信じられませんが。
今回はふっと思いついて数字をインクリメントするプログラムを書きました。
ソースコードを書いて実行してテストしましたが、うまくいきました。
少しでもプログラミングの経験がある人なら
「数字をインクリメントして返す」
というプログラムなんて簡単だと思うかもしれません。
端的に書けば、
return int + 1;
で終わりますからね。
でも、私が書いたプログラムは一味違います。
上記のプログラムではint幅、もしくは大きくてもlong幅以上の整数を
+1して返すことは出来ません。
オーバーフローになりますから。
その欠点を克服し、long幅を超えた整数でも+1して
返すことが出来るプログラムを考えました。
public class Incrementor
{
public string number = null;
public void execute()
{
number = "0" + number;
int[] digits = new int[number.Length];
for( int i = 0; i < digits.Length; i++)
{
digits[i] = Convert.ToInt32(number[i] - 48);
}
digits = recursive(digits, digits.Length - 1);
number = string.Empty;
for( int i = 0; i < digits.Length; i++)
{
number += digits[i];
}
number = number.TrimStart(new char[] {'0'});
}
private int[] recursive(int[] digits, int index)
{
digits[index]++;
if (digits[index] == 10)
{
digits[index] = 0;
return recursive(digits,index - 1);
}
else
{
return digits;
}
}
public static void Main(string[] args)
{
Incrementor incrementor = new Incrementor();
incrementor.number = args[0];
incrementor.execute();
Console.Write("answer : ");
Console.WriteLine(incrementor.number);
}
}
PS C:\Lunamaria> C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc -nologo test.cs
PS C:\Lunamaria> .\test 21474839999
answer : 21474840000
PS C:\Lunamaria> .\test 99999999998
answer : 99999999999
PS C:\Lunamaria> .\test 99999999999
answer : 100000000000
といっても、純粋な整数型ではなく文字列型なので使える場面は限られます。
例えばデータベースでTEXT型の主キーカラムを持つテーブルがあったとして
そのカラムにシーケンシャルな数字を入れていくときなどです。
多分、bigint以上のレコードを格納できるはずです。
なにげに単純なループではなくオシャレに再帰で回しています。
どーすか?
これ、どーすか!?
HTML上でソースコードを書くとインデントがうまくいかないのが不便です。
たまにインデントにこだわる人がいて、
・タブインデント
・全角スペースインデント
・半角スペースインデント
が混ざると半ギレになる人もいますね。
>>つか、Linuxライクな環境に慣れているとファイル名やディレクトリ名に
>>半角スペースを入れるなんて違和感ありすぎて信じられませんが。
( ゚Д゚)ノシ 大抵スペースの代わりにアンダースコア、文節になるタイプだとハイフンを入れる人ですw
なので「お前の作ったファイルは一瞬で分かる」と褒められてる様で変なファイルを仕込んだりするイタズラ出来ないズラ・・・
※過去やったイタズラで一番実用的だと思ったのは「フォルダ開きまくった状態をSSで撮影>それを壁紙」にするって妨害工作(笑)
>>HTML上でソースコードを書くとインデントがうまくいかないのが不便です。
HTMLというより、このBlog上では、ってところですが、コレは同じく思います・・・なんで、全角スペースを1つ挟む事で対処してますね。
※確か普通のHTML上では1つのインデントは出来た筈です(全角スペース2個分で)
>>たまにインデントにこだわる人がいて、
>>・タブインデント
>>・全角スペースインデント
>>・半角スペースインデント
>>が混ざると半ギレになる人もいますね。
大学時代に後輩が授業でテキストエディッタでWebページを作らされた時に、「ホームページ作けど、一度間違ってないか見てください」って言われて見たらインデント滅茶苦茶で頭に来て普通に書き直しをさせた人ですんでw
「お前何の為のインデントやねんボケ!ミテクレで使うんだったら使うな!命令の開始と終了を明確に区分するモンをズラして何がしたいねんカス!これやったらビルダーで作ったゴミタグ削除しただけの方がまだ見れるわ!」と、言った人でごめんなさいっ!
なお、この時のファイルのインデントが半角と全角やタブならまだしも、始点と終点が縦で繋がらないという無茶苦茶なインデント・・・インパクトもさることながら、これでエラーチェックとか「もうオレが一から作り直す方が絶対に楽」って作業で泣きますw
ちなみに、実はその日は自分のWebページの使用ツール変更問題で、過去がネコミでのHTML作成だったので、DWに環境移行した時にインデントの修正(規則性が違う為変更の作業必須)を昨晩からやりつつ、更新ネタを作ってたら徹夜になってしまった状態で見せられた訳で、9割八つ当たりですw
この時の修正ファイル数が確か110で作成が4ファイルw
今のWebページ構成ファイル数?・・・338ファイルw
・・・これが一般的なWebページで3年の間に増える量なのか?と疑問も出ましたw
by Aya (2009-11-10 23:11)
すみません、違う話で申し訳ないのですが・・・
C#でGridvewを使ったことがあると思いますが、
半角英数字の場合、セルを折り返し設定にしても
折り返えしてくれません(全角はok)。
→どうも英語圏で作られているので、半角は単語とみなされ
折り返さない仕様らしいです。
この解決策(折り返す)はご存じではないでしょうか??
やはり描画時のイベントで描画する文字を拾って
自分で書くしかないのかなぁ・・・(試したことはないのですが)
ご面倒でしたら、無視してくださっても構いません。
by ロック (2009-11-11 00:19)
◆ Aya さん
◇ コメントありがとうございます
> 大抵スペースの代わりにアンダースコア、文節になるタイプだとハイフンを入れる人ですw
私はハイフンすら使わずにアンスコでつなげちゃいますね。
ハイフンだとプログラミング言語ではマイナスを表す予約語になってしまうので。
> ※確か普通のHTML上では1つのインデントは出来た筈です(全角スペース2個分で)
HTMLはもっと書いたままで表示して欲しいと思っちゃいますねぇ。
まぁ、PREタグを使えばプレインテキストで書けますけども。
> 始点と終点が縦で繋がらないという無茶苦茶なインデント・・・
そんなデコボコなインデントは見るに耐えませんね・・・。
こういうのって気にしない人はホントに気にしないので、
「感性の違い」ってやつをまざまざと見せ付けられます。
by Lunamaria (2009-11-11 23:47)
◆ ロック さん
◇ nice & コメントありがとうございます
> この解決策(折り返す)はご存じではないでしょうか??
GridViewや折り返しのことが出てくるということはASP.NETでしょうか。
すみません、FormベースのプログラムでDataGridなら使ったことがあるんですが
ASP.NET@C#はあまり詳しくないもので・・・。
既にご存知かもしれませんが、この辺のスレはどうでしょうか。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=46285&forum=7
by Lunamaria (2009-11-11 23:50)