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

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

ストーリー 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にならなかったりしますが設計思想の違いですね。)

  • 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日 18時40分 (#3389332)

    アップルといい、マイクロソフトといい…。
    大企業って殿様商売のところ多すぎますね。
    利用者のことを、もっと考えてほしいです。

    ここに返信
    • by Anonymous Coward on 2018年04月06日 18時52分 (#3389347)

      本件については、マイクロソフトを責める気にならない。計算機の挙動として納得できてしまうので。
      しょせんはデジタル。アナログな数値を表現するには限界があるんだよねえ。
      #利用者フレンドリーじゃないのは認めるけど・・・でも、高校で「近い数値同士を引く時は気をつけろ」って習ったよね?

      • by Anonymous Coward

        右に同じ.
        1わる3かける3が「0.999999」になるようなもんだと思う。

        数式を解析して誤差を最小にする仕組みの有無の問題だから、
        安価な電卓だとこれが仕様になる.
        #50ヘルツ専用の時計を60ヘルツの電源に繋ぐようなもんで。

    • by Anonymous Coward

      ???「本当にその事象で困った人だけ石を投げなさい」

    • by Anonymous Coward

      NVIDIAの2+2=4.1も忘れちゃいけないw

    • by Anonymous Coward

      √2とか計算させてもきっちり正確な値は表示されないじゃん。√4とかだけは、たまたま上手く行くべきだ、ってのが間違い。

    • by Anonymous Coward

      こいつ何も理解してないw

      • by Anonymous Coward

        そうは言っても一般人はIEEE754どころか浮動小数点数の存在すら知らないだろうしねぇ
        説明が難しいよ

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

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

    ここに返信
    • by Anonymous Coward

      今回の修正前の挙動については、以下のページに書かれてますね。
      https://blogs.msdn.microsoft.com/oldnewthing/20160628-00/?p=93765 [microsoft.com]

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

      それで合ってるようです。

      • by Anonymous Coward

        >exp(½ ln x)
        それはそもそも精度的にあんまりよろしくないような…。
        任意のべき乗根を出す計算ボタンならともかく、「√」のボタンなら
        https://cpplover.blogspot.jp/2010/11/blog-post_20.html [blogspot.jp]
        のようなアルゴリズムもあるし、
        手計算でやった筆算アルゴリズムを使ってもよさそうだし…。

  • 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

      それをアドホックというのはおかしい。
      そもそも整数と小数は分けて考えないといけない。
      十進数の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

            自己レス。やはり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

              そのページにも、任意精度なのは四則演算だけで平方根などは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

                任意精度演算って必ず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]

typodupeerror

アレゲは一日にしてならず -- アレゲ研究家

読み込み中...