パスワードを忘れた? アカウント作成
13569696 story
Windows

Windowsの標準電卓で4の平方根が2でなかった仕様、変更される 81

ストーリー by hylom
どうやって修正したのだろう 部門より

Windows 10の電卓アプリで、「4の平方根が2にならない」不具合が修正されたとのこと(PC Watch)。

これは電卓アプリが内部的に32桁精度の浮動小数点演算で計算を行っているためで、4の平方根(√4)を計算すると表示上は2に見えるが、内部的には「1.99999999999999999989317180305609」という値になっており、この結果を使ってそのまま計算すると不具合が発生することがある。たとえば「√4-2」が「-1.068281969439142e-19」になってしまうそうだ。

当初Microsoftはこの挙動を仕様としていたが、このたびこの問題を修正するアップデートが配信されたそうで、これによって4の平方根は2になるという。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by Anonymous Coward on 2018年04月06日 17時51分 (#3389277)

    一般の電卓はどういうアルゴリズムになっているのだろう
    電卓マニアさん、教えてください
    (電卓でIEEE754使っているということはないよね?)
    とか考えていたらやはり実装は色々みたい
    http://verifiedby.me/adiary/097 [verifiedby.me]

    • by Anonymous Coward

      アプリではない普通の電卓は基本的にはBCDの浮動小数です。
      極少数binaryの電卓もありましたが、ほとんどはBCDです。
      例えばCasioやSHARPの関数電卓は内部的にはguard digit込みで15桁の精度があります。(表示は12桁)

      • by Anonymous Coward

        すいません勘違いしていました。端数処理や桁落ち時の処理の話でしたね。
        仰る通り、この辺りは各社様々です。
        桁落ちの他にもπ/n rad付近の三角関数やべき乗の扱い方等メーカー毎に違いがでてきます。
        HPのように敢えて何もしないメーカーもあります。(だからsin(π)が0にならなかったりしますが設計思想の違いですね。)

  • 「1.99999999999999999989317180305609」という数字全体の精度は(先頭の1を除けば)32桁なのに、9が連続している部分が18桁ぐらいしかないのがポイント。
    計算機アプリの内部数値表現は32桁精度なのに、ルートの計算だけは拡張倍精度浮動小数点数(80ビット、仮数部の精度が約19桁)で行われてると推測される。

  • by Anonymous Coward on 2018年04月06日 18時28分 (#3389319)

    .NET Frameworkにはそもそも単精度実数向けのSqrt()関数がないっぽいので、そのためかもしれない。
    電卓も倍精度で計算するように直せばいいのでは。

    PS> ([math]::sqrt(4)-2).tostring("e20")
    0.00000000000000000000e+000
    PS> ([math]::sqrt(0.04)-0.2).tostring("e20")
    0.00000000000000000000e+000

    0.1は想定通り誤差が出る。

    PS> (0.1).tostring("e20")
    1.00000000000000010000e-001

  • by Anonymous Coward on 2018年04月06日 17時52分 (#3389281)

    Win7の電卓でも再現出来たし……?

    • by Anonymous Coward

      XPの電卓でも再現しますが挙動が違うようです。
      XPの電卓:
      -8.1648465955514287168521180122928e-39
      7の電卓:
      -1.068281969439142e-19
      10の電卓(?):
      -1.068281969439142e-19

      XPの方が精度高いんかな。
      計算結果から進数変換したいときとか7のでも大分イライラするからXP(XP Modeから回収)の電卓動かしたほうが便利なんじゃないかと思ってしまう。

      ていうか#3389277 [srad.jp]のリンク先でも言及されてるような過桁落ちされると電卓としては困ったことになる気が。
      Excelの過桁落ちだって結構色々と批判されてるっていうのに(発生条件がゆるすぎるせいかもだが)……

  • by Anonymous Coward on 2018年04月06日 17時54分 (#3389283)

    「√16-4」とかどうなるんだろう

    #私が昔計算系のアプリ作ったときはほとんどの部分を素因数分解で処理したなぁ

  • by Anonymous Coward on 2018年04月06日 17時58分 (#3389290)

    アドホックに修正
    https://twitter.com/ockeghem/status/982136647251718148 [twitter.com]

    • by Anonymous Coward on 2018年04月07日 0時39分 (#3389591)

      修正完了、コミット…と

      if (x == 4.0) return 2.0;
      else if (x == 0.04) return 0.2;
      else return sqrt(x);

      親コメント
    • by Anonymous Coward on 2018年04月08日 7時52分 (#3390096)

      元記事に、完全平方(perfect square)の場合を検出して正確な平方根を返すようにしたとちゃんと書いてるんだが、誰も読んでないのか。hylomが読んでいないのは当然としても。

      修正方法が分かれば、隣のツリーで盛り上がっているような小数の場合が修正されていないことも完全平方の定義からまったく不思議はないとわかる。

      親コメント
    • by Anonymous Coward

      それをアドホックというのはおかしい。
      そもそも整数と小数は分けて考えないといけない。
      十進数の0.04自体を二進数で正確にあらわせないし。

      整数の平方根は無理数になるか整数になるかどちらかなので、
      今回のやつはそれを真面目に判定するようになっただけのこと。
      https://ja.wikipedia.org/wiki/%E5%B9%B3%E6%96%B9%E6%95%B0 [wikipedia.org]

      • by Anonymous Coward

        √0.0625-0.25もダメなので、正直かなり精度が低いのは確か。
        PC Watch記事中の「32桁精度の浮動少数計算」って、まさか単精度実数のことじゃないよね?

      • by Anonymous Coward

        > 十進数の0.04自体を二進数で正確にあらわせないし。

        浮動小数点では正確に表せないというなら同意しますけど、単なる分数なんだから二進数であらわせないまで言うと言い過ぎでしょ。分子と分母を値として保持すればいいんだから。

  • by Anonymous Coward on 2018年04月06日 18時13分 (#3389306)

    単精度,いわゆる float のことを言ってるんだろうけど
    floatはデータサイズが32bits(つまり2進数で32桁)なだけで
    32桁精度ではありません.

    英文を誤訳してると思います.

    • by Anonymous Coward on 2018年04月06日 18時49分 (#3389343)

      > 単精度,いわゆる float のことを言ってるんだろうけど

      言ってないですよ。MSのリリースによると、電卓では四則演算と整数のべき乗以外の演算は"an extended precision library that produces 32 digits of precision"が使われているということなので、誤訳じゃないと思います。
      # そもそもfloatの精度じゃ1.99999999999999999989317180305609なんて値は表現できない

      親コメント
      • by Anonymous Coward

        先頭の"1."を除けばちょうど32桁ですな。精度が高すぎるために誤差が可視化されてしまった(doubleなら丸められてた)可能性が?

        • by Anonymous Coward

          自己レス。やはりdoubleだと丸められますね。

          PS> [double]::Parse("1.99999999999999999989317180305609")
          2

          doubleの10進数の精度は約16桁なので、有効桁数が2倍ということは、128-bit floating numberを使ってそうです。

          • by Anonymous Coward on 2018年04月06日 19時57分 (#3389414)

            自己レス。やはりdoubleだと丸められますね。

            PS> [double]::Parse("1.99999999999999999989317180305609")
            2

            doubleの10進数の精度は約16桁なので、有効桁数が2倍ということは、128-bit floating numberを使ってそうです。

            違います。Windows98からは任意精度演算ライブラリを使っています。
            https://blogs.msdn.microsoft.com/oldnewthing/20040525-00/?p=39193 [microsoft.com]

            親コメント
            • by Anonymous Coward on 2018年04月06日 20時52分 (#3389468)

              そのページにも、任意精度なのは四則演算だけで平方根などは32桁精度(32 digits of precision)で行われるって書いてますよ。

              > Today, Calc's internal computations are done with infinite precision for basic operations (addition, subtraction, multiplication, division) and 32 digits of precision for advanced operations (square root, transcendental operators).

              親コメント
              • by Anonymous Coward on 2018年04月06日 21時13分 (#3389479)

                任意精度演算って必ずinfinite precisionである必要はないです。
                必要に応じて桁数を可変できるのが任意精度です。
                (あと任意精度演算の~桁精度というのはbinary64やbinary128等2進数浮動小数の~桁精度相当というものとは別です。)
                現実には無限に桁を増やすのは得策ではない等の事情で桁数を制限して使っています。
                下の方に同じ任意精度演算ライブラリを用いたPower Calculator PowerToyは512桁精度って書いてありますね。

                親コメント
            • by Anonymous Coward

              違うよ。それは四則演算とべき乗だけ。
              https://blogs.msdn.microsoft.com/oldnewthing/20160628-00/?p=93765 [microsoft.com]

              Specifically, it uses an arbitrary precision arithmetic library for rational operations: addition, subtraction, multiplication, division, and raising to a positive integer power. Other operations use an extended precision library that produces 32 digits of precision.

              "extended precision"という用語は一般に浮動小数点数に使う用語(Wikipedia [wikipedia.org])だし、有効

    • by Anonymous Coward

      なんでdouble使わないんだろう?
      floatじゃないと速度が出なくて困るようなアプリケーションでもあるまいに。

    • by Anonymous Coward

      結局のところは浮動小数の精度がどんなに上がっても解決しない問題かもしれません

      計算速度低下は止むを得ないですが
      新たな選択肢として固定小数decimal(numeric)で計算できる様に成って欲しいものです

    • by Anonymous Coward

      WIndows98以降の電卓は任意精度演算ライブラリを使っていまして、
      ちゃんと32桁精度があります。

      https://blogs.msdn.microsoft.com/oldnewthing/20040525-00/?p=39193 [microsoft.com]

  • 対数とって、2で割り、真数に戻してるんでしょうか?

    #昔は手計算でルートを開かせられたんだ…
    #私は覚えていないです。だって電卓あったし…

typodupeerror

弘法筆を選ばず、アレゲはキーボードを選ぶ -- アレゲ研究家

読み込み中...