けものフレンズBBS NEO

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

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そのものとして扱われるので、「同じ」という扱いになる
    という事かも(合ってる保証は全くなし)