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#]TextBoxで、マウスクリック(1回目)だけ、内容を全選択させる

TextBoxの内容を全選択させるには、SelectAll()を使用 マウスの1回目も含めるなら、BeginInvoke~を使用 VB.net版はこちら。 日本の中心付近で仕様変更と闘うSE日記[VB …

ORACLEでORA-01861: リテラルが書式文字列と一致しません

ORA-01861: リテラルが書式文字列と一致しません このエラー、ぶっちゃけ、意味が分からないところでもある。 日付の指定時に発生してて、原因が判明するまでに結構回り道をしました。 ネットで検索し …

no image

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

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

VisualStudioでデータテーブルの中身確認できるの便利すぎワロタw

DataSetビジュアライザーで、DataTableの中身が確認できるのが便利すぎたのでメモ。 データテーブルって気軽に使えるけど、中身の確認がしち面倒くさい件 本当のところはどうなのか?ってのは知ら …

[C#]comboBoxでマウスホイールによる値の変更を禁止する

comboBoxってあるじゃないですか。 アレのお話。 勝手に値が変わってしまうコントロールがある いや、勝手にじゃなく、操作の結果なんだけども・・・ という、こちらの理論は当然ながらお客さんには通じ …


カテゴリー