ChromeでMath.log2の精度が変更されました

ステファン・ムサラ

要素の数に基づいて二分木の深さを計算するJavaScriptプログラムを作成しました。私のプログラムは何ヶ月も正常に動作していますが、最近、ChromeとFirefoxでWebページを表示したときに違いが見つかりました。

特に、Firefoxの場合:

Math.log2(8) = 3

しかし今Chromeでは:

Math.log2(8) = 2.9999999999999996

私のJavaScriptプログラムは元々、要素の数に基づいてバイナリツリーの深さを見つけるために作成されました。

var tree_depth = Math.floor(Math.log2(n_elements)) + 1;

Chromeでも正しく機能するように、この数式に簡単な変更を加えました。

var epsilon = 1.e-5;
var tree_depth = Math.floor(Math.log2(n_elements) + epsilon) + 1;

2つの質問があります:

  1. 最近Chromeの精度が変わったことに気付いた人はいますMath.log2か?

  2. イプシロンを追加して上記で行ったものよりもエレガントな変更はありますか?

カンタス94ヘビー

注: Math.log2 V8で実装されて以来、実際には変更されていません。Chromeが独自の実装を含める前に、覚えていないか、これらの特殊なケースで正しい結果が得られるシムを含めていた可能性がありMath.log2ます。

また、Math.ceil(x)ではなく使用する必要があるようですMath.floor(x) + 1

どうすればこれを解決できますか?

JavaScriptのさまざまな実装間での依存Math.logMath.log2正確さを回避​​するために(使用されるアルゴリズムは実装定義です)、バイナリツリーに2 32未満の要素がある場合は、ビット演算子を使用できますこれは明らかにこれを行うための最速の方法ではありませんが(これはO(n)のみです)、比較的単純な例です。

function log2floor(x) {
  // match the behaviour of Math.floor(Math.log2(x)), change it if you like
  if (x === 0) return -Infinity;

  for (var i = 0; i < 32; ++i) {
    if (x >>> i === 1) return i;
  }
}

console.log(log2floor(36) + 1); // 6

Math.log2現在、さまざまなブラウザでどのように実装されていますか?

彼らはの値の乗算に依存しているとして、Chromeの現在の実装では不正確であるMath.log(x)ことでのMath.LOG2Eエラー(丸めにそれが影響を受けやすく、ソースを):

// ES6 draft 09-27-13, section 20.2.2.22.
function MathLog2(x) {
  return MathLog(x) * 1.442695040888963407;  // log2(x) = log(x)/log(2).
}

Firefoxを実行している場合は、ネイティブlog2関数を使用するか(存在する場合)、そうでない場合(Windowsなど)はChromeと同様の実装を使用しますソース)。

唯一の違いは、乗算する代わりに、次のように除算するlog(2)ことです。

#if !HAVE_LOG2
double log2(double x)
{
    return log(x) / M_LN2;
}
#endif

double
js::math_log2_impl(MathCache *cache, double x)
{
    return cache->lookup(log2, x, MathCache::Log2);
}

double
js::math_log2_uncached(double x)
{
    return log2(x);
}

bool
js::math_log2(JSContext *cx, unsigned argc, Value *vp)
{
    return math_function<math_log2_impl>(cx, argc, vp);
}

他のすべてのコードは、結果をテーブルにキャッシュすることだけですが、Chromeは行いません。これはFirefoxのMath.log2機能の精度には影響しません

掛け算または割り算:どのくらいの違いありますか?

による除算Math.LN2と乗算の違いをテストMath.LOG2Eするには、次のテストを使用できます。

function log2d(x) { return Math.log(x) / Math.LN2; }
function log2m(x) { return Math.log(x) * Math.LOG2E; }

var pow = Math.pow;

// 2^1024 rounds to Infinity
for (var i = 0; i < 1024; ++i) {
  var resultD = log2d(pow(2, i));
  var resultM = log2m(pow(2, i));

  if (resultD !== i) console.log('log2d: expected ' + i + ', actual ' + resultD);
  if (resultM !== i) console.log('log2m: expected ' + i + ', actual ' + resultM);
}

どの関数を使用しても、特定の値1に対して浮動小数点エラーが発生することに注意してくださいの浮動小数点表現がlog(2)実際の値よりも小さいため、実際の値より高い値になります(一方log2(e)は低くなります)。これは、を使用log(2)すると、これらの特殊なケースの正しい値に切り捨てられることを意味します。

1: log(pow(2, 29)) / log(2) === 29.000000000000004

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

負の値を除外した後でも、log2でゼロ除算の警告が発生しました

分類Dev

Chromeのホームページが変更されました

分類Dev

ピカソで画像の向きが変更されました

分類Dev

IPythonで配列要素のIDが変更されました

分類Dev

$ localStorageの値がfabricjsで変更されました

分類Dev

pm3dでgnuplotのzrangeが変更されました

分類Dev

行が変更されました、あなたの変更はodoo9で破棄されます

分類Dev

2回目のクリックでredux状態の値が変更されました

分類Dev

Angular 2:ブラウザでURLが変更されましたが、ビューが表示されません

分類Dev

D3のdefer()に関数を入れると、console.log内のデータ構造が他の関数で変更されました

分類Dev

SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

分類Dev

SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

分類Dev

SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

分類Dev

SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

分類Dev

MDメンバー名がec2で変更されました

分類Dev

Tensorflow - tf.nn.conv2D() で Weight 値が変更されましたか?

分類Dev

Chromeの新しいタブページが変更されましたが、元に戻したい

分類Dev

FirefoxでJavascriptの新しいDate()が変更されましたか?

分類Dev

nodeJSで変数値が予期せず変更されました

分類Dev

__init__からの変数が1つの関数で変更されましたが、他の関数への変更として認識されません

分類Dev

親の状態が変更された後、ReactJsの子が更新されませんでした

分類Dev

console.logが変更される前に変更された値を出力するのはなぜですか?

分類Dev

Python pandasdatareaderがyahooで機能しなくなりました-financeのURLが変更されました

分類Dev

array_unique()が7.1と7.2の間で変更されました

分類Dev

C#.netでDatagridviewの色が間違って変更されました

分類Dev

Swift5の移行で循環イメージが変更されました

分類Dev

CultureInfoのNumberFormat.PercentPositivePatternがWindows10マシンで変更されました

分類Dev

/ proc / meminfoで同期した後、どの行が変更されますか?

分類Dev

Visual Studio 2015でAssembly.GetTypes()の動作が変更されました

Related 関連記事

  1. 1

    負の値を除外した後でも、log2でゼロ除算の警告が発生しました

  2. 2

    Chromeのホームページが変更されました

  3. 3

    ピカソで画像の向きが変更されました

  4. 4

    IPythonで配列要素のIDが変更されました

  5. 5

    $ localStorageの値がfabricjsで変更されました

  6. 6

    pm3dでgnuplotのzrangeが変更されました

  7. 7

    行が変更されました、あなたの変更はodoo9で破棄されます

  8. 8

    2回目のクリックでredux状態の値が変更されました

  9. 9

    Angular 2:ブラウザでURLが変更されましたが、ビューが表示されません

  10. 10

    D3のdefer()に関数を入れると、console.log内のデータ構造が他の関数で変更されました

  11. 11

    SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

  12. 12

    SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

  13. 13

    SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

  14. 14

    SaucyでAppindicatorまたはGtkMenuAPIが変更されましたか?

  15. 15

    MDメンバー名がec2で変更されました

  16. 16

    Tensorflow - tf.nn.conv2D() で Weight 値が変更されましたか?

  17. 17

    Chromeの新しいタブページが変更されましたが、元に戻したい

  18. 18

    FirefoxでJavascriptの新しいDate()が変更されましたか?

  19. 19

    nodeJSで変数値が予期せず変更されました

  20. 20

    __init__からの変数が1つの関数で変更されましたが、他の関数への変更として認識されません

  21. 21

    親の状態が変更された後、ReactJsの子が更新されませんでした

  22. 22

    console.logが変更される前に変更された値を出力するのはなぜですか?

  23. 23

    Python pandasdatareaderがyahooで機能しなくなりました-financeのURLが変更されました

  24. 24

    array_unique()が7.1と7.2の間で変更されました

  25. 25

    C#.netでDatagridviewの色が間違って変更されました

  26. 26

    Swift5の移行で循環イメージが変更されました

  27. 27

    CultureInfoのNumberFormat.PercentPositivePatternがWindows10マシンで変更されました

  28. 28

    / proc / meminfoで同期した後、どの行が変更されますか?

  29. 29

    Visual Studio 2015でAssembly.GetTypes()の動作が変更されました

ホットタグ

アーカイブ