けものフレンズBBS NEO

学生フレンズ集まれ!~ジャパリ学園~ / 1841

1841
クモハ223-2046 2018/04/01 (日) 15:03:27

ふええ理論の話とかもう全然分からんし頭爆発しそう
前に授業で、世の中にはコンピューターには解けない問題の方が多いとかなんとか聞いたような
コンピューターは有限回の試行しかできない(って書いてあった)という事と関係あるのかな
どんどん数を0に近づけていくと、連続した普通の?数学なら極限という概念により「限りなく0に近づく」ということが考えられるし、そう習った(極限の問題は未だに全然できない)
でも、コンピューターはそれができないから、ある一定以下になると0に合わせて切り捨てる(計算機イプシロンだっけ?)から必ず誤差が生じる
同じように、小数は2進数だと循環小数になる場合が多い(0.1(10)=0.00110011...(2))が、やはり循環小数という「無限」を伴う概念はコンピューターには完璧に扱えず、誤差が生じる

if (0.1 + 0.2 == 0.3){
     printf("合ってる\n");
  }else{
     printf("違う\n");
  }

これ実行すると、「違う」って言われるんですよね
小数をフルに表示させたら「0.1 + 0.2 = 0.3000000000000000444089209850」って言われましたし

通報 ...
  • 1843
    頂(キ ・マ・ス)◆jttgGfj/xQ 2018/04/01 (日) 15:18:47 >> 1841

    コンピューターは無限を無限のまま計算するからじゃないの?

  • 1845
    アデリーペンギン 2018/04/01 (日) 16:09:10 >> 1841

    型の問題では?
    おそらくdecimal型なら誤差は発生しないかと

    1848
    アデリーペンギン 2018/04/01 (日) 16:24:10 修正 >> 1845

    C#ですが

    if (0.1 + 0.2 == 0.3){
     Console.WriteLine("合ってる");
    }else {
     Console.WriteLine("違う");
    }
    if ((decimal)0.1 + (decimal)0.2 == (decimal)0.3){
     Console.WriteLine("合ってる");
    }else {
     Console.WriteLine("違う");
    }
    

    実行結果
    違う
    合ってる

    (decimal)を三回も書かなくても同じ処理ができるようなスムーズな書き方ってあります?(初心者)

    1849
    アデリーペンギン 2018/04/01 (日) 16:54:17 >> 1845

    0.1m + 0.2m == 0.3mという書き方もできるのですね、初めて知りました(自己解決)

    1852
    クモハ223-2046 2018/04/01 (日) 17:09:01 修正 >> 1845

    ワイトはCの事しか知らんから全然分からん!
    調べたらdecimal型は内部で10進数で値を保持してるようですね
    この誤差は2進数で小数を上手く表せない事に起因しているので確かに10進数で扱えばこの問題は起きませんね
    (10進数で保持なんてどうやってやってるんだろ...)

    不思議なのがCでもfloatにしたら誤差がなくなるんですよね...

    if (0.1 + 0.2 == 0.3){
       printf("合ってる\n");
    }else{
      printf("違う\n");
    }
    if ((float)0.1 + (float)0.2 == (float)0.3){
       printf("合ってる\n");
    }else{
       printf("違う\n");
    }
    //実行結果:
    //違う
    //合ってる
    

    これの理由がイマイチ分からない...
    この誤差は自分の環境で5.5×10-15程度なのでfloatでも普通に入る気がするんですが...

    1857
    クモハ223-2046 2018/04/01 (日) 17:24:44 >> 1845

    float型にキャストしたことにより有効数字が減って結果差がなくなったとかそんなんか...?
    じゃあなんでdoubleだと消失が起こらない...?

    1868
    クモハ223-2046 2018/04/01 (日) 18:03:19 >> 1845

    >> 1857
    分かったかも
    倍精度浮動小数点数の計算機イプシロンは約2-52=2.2×10-16らしい(複数定義があるらしいが分からん)
    doubleの有効桁数が15か16らしいので、イプシロンがギリギリ仮数部に入るから「違う」と言われる
    しかし、float型は有効桁数が7桁程しかないので、マイナス10乗オーダーの誤差を入れることができず、1.000000×10-1そのものとして扱われるので、「同じ」という扱いになる
    という事かも(合ってる保証は全くなし)

  • 1851
    ひねもす 2018/04/01 (日) 17:03:17 >> 1841

    最近の僕の気になるCPU命令セットRISCVだと
    十進の浮動小数点演算が対応する予定らしいんですよね。
    浮動小数は非正規表現とか調べると深い。

    第505回 オープン規格の新しい命令セットアーキテクチャRISC-V入門 ツールチェインを用意する
    2017年には新しい命令セットアーキテクチャである「RISC-V」の話題が盛り上がりました。今回はUbuntu上でRISC-V用のツールチェインをエミュレーターを導入し,実行してみましょう。
    gihyo.jp

    1860
    クモハ223-2046 2018/04/01 (日) 17:26:51 >> 1851

    ええ..もうアーキテクチャレベルで10進数を扱う時代ですか...
    何かもうコンピュータの発展は凄まじいですね