2020年09月11日
川俣晶の縁側ソフトウェアC# コーディング How Tototal 1447 count

【入門級】0で割っても例外が起きないことがある?

Written By: 川俣 晶連絡先

型を変えただけなのに §

 サンプルソースのdiv1のようにdecimal型の割り算を行うメソッドがあるとします。

 0を0で割ると【ゼロで割った】という例外が起きます。

 ところが、【decimal型をやめてdouble型に変更してよ】と言われてサンプルソースのdiv2

のように書き換えると他には何も変更していないのに例外が起きなくなり、その代わりにNaNという数値ではない謎の文字が出力されるようになりました。

 なぜでしょう?

NaNは数値ではない数値 §

 NaNとは、非数(Not a Number)を示す浮動小数点数値の状態です。

 つまり、数値の一種であって、数値ではありません。

 C#の数値型には、このような状態を表現する能力を持っている型と持っていない型があります。持っているのはfloat/doubleです。持っていないのはそれ以外の全てです。

 0を0で割った結果の値は数値としては表現できないので、NaNという状態になります。

 ちなみに、0意外の数を0で割ると∞等の状態になります。これも、数値の一種でありながら数値ではない状態です。

 NaNを表現する機能を持っていない型の場合は状態がNaNになることはできないので、例外が起きます。つまり、型を書き換えるだけで動作が変わります。

罠の数々 §

  • 表現力の乏しい型の方が、より省メモリで速い可能性が高い。そのため、表現力の乏しい型も積極的にサポートされている。必要なニーズを満たす最小の型を調べてそれを使うとそれだけで性能アップが期待できる
  • 表現力の高い型は、NaNや∞のような数値であって数値ではない状態に簡単に入るので、必ず何かの数値になると期待してはいけない。
  • DivideByZeroExceptionは0で割った時に必ず起こるわけではない。それは型に依存する

参考リンク §

算術演算子 (C# リファレンス)

DivideByZeroException クラス

 どの型で割り算した時に例外になるかの条件は、実は算術演算子の説明ページではなく、DivideByZeroException クラスのページに書いてある。チェックしてみよう。

リポジトリ §

https://github.com/autumn009/cshowto

DivByZero §

using System;

class Program

{

    private static void div1(decimal x, decimal y)

    {

        Console.WriteLine(x / y);

    }

    private static void div2(double x, double y)

    {

        Console.WriteLine(x / y);

    }

    static void Main()

    {

        Console.WriteLine("div1の利用");

        try

        {

            div1(0, 0);

        }

        catch (DivideByZeroException)

        {

            Console.WriteLine("0で割りました。");

        }

        Console.WriteLine("div2の利用");

        try

        {

            div2(0, 0);

        }

        catch (DivideByZeroException)

        {

            Console.WriteLine("0で割りました。");

        }

    }

}

実行結果

div1の利用

0で割りました。

div2の利用

NaN

Facebook

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?
キーワード【 川俣晶の縁側ソフトウェアC# コーディング How To
【C# コーディング How To】の次のコンテンツ
2020年
09月
12日
【入門級】マイナス計算が値を変化させないとき
3days 0 count
total 1411 count
【C# コーディング How To】の前のコンテンツ
2020年
09月
10日
【入門級】byte型の加算がコンパイル・エラーになるケースがある!?
3days 0 count
total 830 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20200911095101
サイトの表紙【C# コーディング How To】の表紙【C# コーディング How To】のコンテンツ全リスト 【C# コーディング How To】の入手全リスト 【C# コーディング How To】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.