C#で計算時の切り上げ・切捨て・四捨五入を行う方法

投稿日:2018-01-18

普段使わないと馴染みが薄いですが、日常で行う計算にも切り上げ・切捨て・四捨五入は割りと使われていたりします。
今回はそんな計算のお話。

例えば、クルマ購入時の端数の切捨てとかね。
「千円の位を負けてくれない?」みたいな感じで。
細かい買い物する時とかに、ざっくり端数を切り上げたり、切り捨てたりして概算することもあるでしょ。

それです。

しかし、この便利さゆえに、PGで扱うには少々厄介なところもある訳です。

なんで今更、四則演算を振り返るの?

なんでこんなに種類を使い分けないといけないんだよ・・・
と嘆きつつ、金額関連の処理をコーディングする必要が発生したのでやらざるを得ない。

今更って感じもするんだけど、修正しているプログラムで使い分けなきゃいけない所があったので、改めて調べてみた。
特に、お金を扱うプログラムだと、小数点以下の端数の違いが積み重なって、数円単位の誤差になる。

誤差が許されない世界がある

で、金額の誤差が出ると、お客さんにど叱られる訳ですw
数円とはいえ、誤差は誤差なので、場合によっては、初期入力のデータから値の洗い出しが発生したりします。
マジで泣けます。

数円なんて、誰かのポケットマネーとかで補填しちゃえばいいじゃない?
って思うでしょ。
やっちゃ駄目なんですよ・・・

自分は簿記資格を持ってるわけじゃないですが、確定申告で必要になる複式簿記の世界になると、入ったものと出たものが同じにならないといけないので。
なので、誤差が出るということは、何かが足りないか、過剰に記録されてしまっているということで。

コンビニでバイトなんかしてるとその時間帯のレジ担当者が自腹で補填なんていう話も聞いたりしますが、それが許されない世界もあるとうことで。

しかも会社によって違ったりする

これも、マジかよ・・・って思うんですが、会社によっては処理ごとに切り上げ・切捨て・四捨五入を使い分けるところもあるので、修正する時にその選択を間違えると、当然お客さんにドヤされますw

巨大な物とかだと、どんぶり勘定(ではないけど)で端数部分(㌧に対しての㌘単位とか)は無視したりするところもあります。

身近なところだと、車とか。
燃費を気にして、入れるガソリンの量とか気にしたりするけど、車に乗せる荷物のなかの本1冊とか、一緒に持ってるスマホとか気にしないでしょ。

そんな感じ。

切り上げ

1.5 → 2
のように小数点以下の端数を繰り上げます。
1.3でも2。
1.9でも2。

double i = 0;

//2になる
i = Math.Ceiling(1.3);

//2になる
i = Math.Ceiling(1.9);

//-1になる
i = Math.Ceiling(-1.5);

切り上げは、そう難しい事も無いので、自分でロジックも組めたりします。
C#ではMath.Ceiling()で実現できますが、言語によっては用意されていなかったり、Mathクラスが使わせてもらえなかったりで、自分で似たような関数を作ることもあります。

唯一気をつけないといけないのは、負の値の場合。

「-1.5」は「-2」ではなく、「-1」なんです。

切捨て

さて、次は切り捨てです。

切り上げとは逆なので、イメージはしやすいかと。

1.5 → 1
のように小数点以下を切り捨てます。
1.3でも1。
1.9でも1。

double i = 0;

//1になる
i = Math.Truncate(1.3);

//1になる
i = Math.Truncate(1.9);

//-1になる
i = Math.Truncate(-1.5);

切捨ては、そう難しい事も無いので、自分でロジックも組めたりします。
C#ではMath.Truncate()で実現できますが、言語によっては用意されていなかったり、Mathクラスが使わせてもらえなかったりで、自分で似たような関数を作ることもあります。

唯一気をつけないといけないのは、負の値の場合。

「-1.5」は「-2」ではなく、「-1」なんです。

四捨五入

さて、次は四捨五入です。

切り上げと切り捨てをミックスした感じです。
感じのとおり、0.4以下を切り捨てて、5以上を切り上げます。

1.5 → 2
のように小数点以下を四捨五入します。
1.3は1。
1.9は2。

double i = 0;

//1になる
i = Math.Round(1.3);

//2になる
i = Math.Round(1.9);

//-1になる
i = Math.Round(-1.3);

//-2になる
i = Math.Round(-1.9);

四捨五入も、そう難しい事も無いので、自分でロジックも組めたりします。
C#ではMath.Round()で実現できますが、言語によっては用意されていなかったり、Mathクラスが使わせてもらえなかったりで、自分で似たような関数を作ることもあります。

気をつけないといけないのは、負の値の場合。
整数と値の増減方向が変わるので、思考のループから抜け出せなくなる事もw
普段は意識して使わないけれど

まとめ

切り上げ・切捨て・四捨五入なんて、実生活で改めるまでも無く使ってる。
ただ、それが日常生活レベルなら、計算の誤差も丼勘定でOK。

プログラムをやる上では、避けて通れないので、改めて理解しておいて損は無い。
多分、正の値の時は問題ないんだけど、負の値になったときに途端にあやふやになる人が多いと思うので。







-C#

関連記事

C#:ソースコードのブロック化は必要?

こんにちは、ブロック化の必要性が理解できないSEもどきですw 皆さんは使ってますか? と、さも開発職の人がこのブログに来てるような書き出しですが、個人的に、このブロック化、使いづらいんですよね。 上手 …

Visual Studio 2008 が重い件について(暫定対応)

現象 とにかく重い。 重いと一言で言うけど、重いという内容は色々含んではいる。 起動が遅い スクロールすらカク付く 右クリックのコンテキストメニューが表示されるまで数秒待たされる 定義の移動に時間がか …

Excelでシートをコピーする時に、「名前が既に存在します。」と言われるのを回避して、Excel出力を早くしたい。

結論から書いてしまうと、名前の重複を削除しても、Excelの出力は別に早くならなかった。 早くなるという意味だと、手動でシートをコピーした時に、いちいちダイアログの対応をしなくて済むので、自分で作業し …

[C#]ToStringメソッドで簡単に桁区切りを実現する方法

結論 ToStringメソッドと書式設定で解決。 int a = 1; int b = 1; int ab = a * b; string c = ""; //「1」になる c = …

no image

ToolTip(ツールチップ)のPictureBoxに登録ものが表示されなくなった

PictureBoxに関連付けてたToolTip(ツールチップ)が表示されなくなる~C# http://ameblo.jp/oregano-blog/theme-10017227400.html 事の …


カテゴリー