2014-01-24 4 views
0

이 질문은 this과 관련이 있습니다. 그러나 속도를 위해 함수를 최적화하려고하기 때문에이 질문을 새로운 것으로 질문합니다.C#의 자바 스크립트 포트 BitConverter.DoubleToInt64Bits

앵거스 존슨의 새로운 floats Clipper library을 자바 스크립트로 번역했으며, Ulps 기술을 사용하여 두 배를 비교하여 동일성을 비교하는 기능이 있습니다 (IsAlmostEqual).

 
var IsAlmostEqual_Ulps = function(A, B) 
{ 
    DoubleToInt64Bits(A, aInt); 
    if(aInt.hi < 0) aInt = subtract(Int64_MinValue, aInt); 
    DoubleToInt64Bits(B, bInt); 
    if(bInt.hi < 0) bInt = subtract(Int64_MinValue, bInt); 
    var sub = subtract(aInt, bInt); 
    if (sub.hi < 0) sub = negate(sub); 
    if (lessthan(sub, maxUlps)) return true; 
    return false; 
} 

내 자바 스크립트 버전은 83 개 샘플 값에 따라 확인을 작동하는 것 같다,하지만 (JSBIN에서)

 
public static bool IsAlmostEqual(double A, double B) 
{ 
    //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 
    const int maxUlps = 10000; 
    Int64 aInt = BitConverter.DoubleToInt64Bits(A); 
    if (aInt < 0) aInt = Int64.MinValue - aInt; 
    Int64 bInt = BitConverter.DoubleToInt64Bits(B); 
    if (bInt < 0) bInt = Int64.MinValue - bInt; 
    Int64 sub = unchecked(aInt - bInt); 
    if (sub > aInt != bInt < 0) return false; 
    return (sub <= 0 && sub > -maxUlps) || (sub > 0 && sub < maxUlps); 
} 

그리고 내 번역 :

원래의 C# 기능은 여기 문제는 천천히, DoubleToInt64Bits 기능에서 오는 주로입니다. 코드가 독립형 html (JSBIN 외부)로 실행되면 총 실행 시간은 약 2267ms이고 그 중 DoubleToInt64Bits은 983ms가 걸립니다.

문제가 (= 느린) DoubleToInt64Bits가 여기에 있습니다 : 빠른 DoubleToInt64Bits을 할 수있는 방법이

 
function DoubleToInt64Bits(A, xInt) 
{ 
    (new Float64Array(buf))[0] = A; 
    xInt.lo = (new Uint32Array(buf))[0] | 0; 
    xInt.hi = (new Int32Array(buf))[1] | 0; 
} 

있습니까?

답변

1

DataView은 버퍼에 다른 형식이 지정된 배열을 만드는 대신 버퍼에서 다른 형식을 읽는 데 더 적합한 클래스입니다. 여기 DoubleToInt64Bits 메서드를 다시 작성하여 DataView을 사용합니다.

function DoubleToInt64Bits(A, xInt) 
{ 
    var dataView = new DataView(buf); 
    dataView.setFloat64(0, A); 
    xInt.lo = dataView.getUint32(4) | 0; 
    xInt.hi = dataView.getInt32(0) | 0; 
} 

이렇게하면 내 실행 시간이 ~ 1500ms에서 ~ 850ms로 단축됩니다.

+0

고마워요! 원래의 코드에서'DoubleToInt64Bits'는 800-1000ms를 필요로합니다. 귀하의 버전을 사용하는 데는 0 ~ 6 밀리 초가 걸립니다. –