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#

関連記事

ORACLEでTO_CHARを使用し、カンマ区切りデータを出力する

帳票出力を行うPGで困った。 数値形式のデータのため、カンマ区切りで表示したいんだけど、テンプレートの制約のせいで上手く行かなくて時の解決方法。 帳票のテンプレートとなるファイルのセルは文字列形式。 …

続) 何度だって引っかかるORACLEのエラー・・・。ORA-01008:バインドされていない変数があります。

この土日は休日出勤でした・・・ そして、昨日・・・新しい現象が発生しました。 日本の中心付近で仕様変更と闘うSE日記日本の中心付近で仕様変更と闘うSE日記http://ht-jp.net/blog/p …

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

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

[C#]$を使ったstring.formatの別の書き方

str += $"(文字列) = {x}"; 保守で、機能修正を行う必要があって、修正をしていたところ、こんな書き方をしているプログラムがありまして・・・ なんだこりゃ??? とな …

devenvを使って、プロジェクトをコマンドラインからビルドする方法[VisualStudio]

今日も今日とて休日出勤\(^o^)/   現在、C#をメイン言語として使用しています。 で、当然というか、開発の区切りだったり、テストするためにビルドというものをやります。 このビルド、プロ …


カテゴリー