2016-10-28 8 views
2

私はC#にJavaScriptからライブラリを変換し、この場合の下で感じたんだからC#で小数ビット単位の操作を行う方法:のJavascriptのコード

私は他の記事に読んだから
// Javascript 
var number = 3144134277.518717 | 0; 
console.log(number); // -> -1150833019 

、それがあったのかもしれませんラウンド値に使用されるが、この場合には値が、私はそれがあることを期待し(それは四捨五入されることになった場合)、私はC#と同じ動作をで再現できないものではありません。

// C# 
3144134277.5187168 | 0 // -> Operator '|' cannot be applied to operands 
         // of type 'double' and 'int' 
// or 
Convert.ToInt64(3144134277.5187168) | 0 // -> 3144134278 

ありがとう助けて!

+0

これは実際に値を四捨五入するために使用されていますが、あなたが知る限り非常に危険です。 JavaScriptのビット単位の算術演算は、数値を32ビットに強制的に変換します。その結果、大きな数値に対してオーバーフローの問題が発生します。 – vlaz

答えて

6

方法JavaScriptで|作品はin the spec詳細ですが、主に何を見ていると、第二引数であるため|が暗黙的にビット単位を行う前に、32ビットのint型へのオペランドを変換することをOR(何もしませんこれは0)。あなたが見ているものは、ToInt32 operationの結果です:

  1. 番号は? ToNumber(argument)(あなたは、主にこのビットを無視することができます。)
  2. を数がNaN+0-0+∞、または-∞であれば、+0を返します。
  3. を、数字と同じ符号で、その大きさがfloor(abs(number))である数学的な値にします。
  4. int32bitは2^int型剰余ことしてみましょう。
  5. 場合int32bit≥2^、int32bit返す - 2^と、それ以外の場合はint32bitを返します。

だから、C#で、私はそれが大体だと思う:

double value = 3144134277.5187168; 
bool negative = value < 0; 
long n = Convert.ToInt64(Math.Floor(Math.Abs(value))); 
n = n % 4294967296; 
n = n > 2147483648 ? n - 4294967296 : n; 
int i = (int)n; 
i = negative ? -i : i; 
Console.WriteLine(i); // -1150833019 

...わかりやすくするために冗長に書かれました。記号は仕様と全く同じ場所に結果に追加されないことに注意してください。私がそれをしたとき、それは正しく動作しませんでした。おそらく、仕様の "モジュロ"とC#の%演算子の間の異なる定義と関係していました。

-3144134277.5187168でこれらの手順を実行すると、1150833019と表示されます。これも同様です。

+1

お世話になりましたT.J.! –