2015-01-13 1 views
0
나는 두 숫자를 추가하려고하지만 잘못된 결과를 얻을 때 올바른 결과

추가 두 숫자는 그래서, 나는 그것이 수의 최대 값을 초과 생각, 올바른 결과

var n1:Number = 2785077255; 
var n2:Number = 100000097214922752; 
trace(Number(n1 + n2));//trace 100000100000000000, not 100000100000000007 
trace((Number.MAX_VALUE - Number(n1 + n2)) > 100);//trace true 

을하지 않는

을하지 않습니다 나는 그것을 테스트하고 내가 생각한 것처럼 거짓을 추적하지 않는다.

+5

당신은 최대 값을 초과하지했습니다 (이 lodgamebox 라이브러리에서 LongInt을 기반으로) 한 번 만든 유틸리티 방법을 사용할 수 있습니다 그러나 당신은'Number'의 최대 정밀도 *를 초과했습니다. – Phylogenesis

+0

@Phylogenesis 그래서 당신이 올바른 결과를 그냥이 같은 숫자를 추가 할 수 없다는 뜻입니까? – Pan

+0

'Number'는 부동 소수점 표현입니다. 64 비트 배정 밀도 값으로 저장됩니다. 자세한 내용은 [이 링크] (http://en.wikipedia.org/wiki/Double-precision_floating-point_format)를 참조하십시오. 기본적으로 임의의 값을 저장할 수 없습니다. – Phylogenesis

답변

1

예, 문제는 @Phylogenesis가 언급 한대로 Number입니다. 실제로는 사마귀의 경우 52 비트가 포함 된 64 비트의 2 배가되지만 결과가 초과되었습니다. 좋은 소식은 lodgamebox에서 두 :)

  1. 일부 BigInteger/LongInt AS3의 구현에서는 정상적 사용을위한 해결 방법, 이벤트, as3crypto에서 예를 BigInteger를 들어, (당신이 그들 중 몇 구글 수) 또는 LongInt이 있음 있습니다

  2. 현재는 곱하기 용이지만 해당 솔루션을 작은 작업으로 수정할 수 있습니다. (임시 배열/바이트 배열의 생성없이) 최적의 성능을 위해 당신은 내가

    /** 
    * Safe multiplying of two 32 bits uint without precision lost. 
    * 
    * Usage: 
    * Default behaviour (with 64 bit Number mantis overflow): 
    *  uint(1234567890 * 134775813) = 1878152736 
    * 
    * Fixed correct result by that method: 
    *  uint(1234567890 * 134775813) = 1878152730 
    * 
    * @param val1 
    * @param val2 
    * @return 
    * 
    */ 
    public static function multiplyLong(val1:uint, val2:uint):uint 
    { 
        var resNum:Number = val1*val2; 
        //52 bits of mantis in 64 bit double (Number) without loose in precision 
        if(resNum <= 0xFFFFFFFFFFFFF) 
         return uint(resNum); 
    
        //count only low 32 bits of multiplying result 
        var i:uint, mul:Number, ln:uint=0, hn:uint=0, _low:uint = val1; 
        for (i = 1<<31; i; i >>>= 1) 
        { 
         if(val2 & i) 
         { 
          mul = _low * i; 
          ln += mul & uint.MAX_VALUE; 
         } 
        } 
        _low = ln; 
    
        return _low; 
    } 
    
+0

알겠습니다. 내 게임의 char id는 64 비트 Number를 사용하고 있으며, 전체 프로젝트에서 Number를 Number에서 LongInt 또는 BigInteger로 변경하는 것은 너무 어렵습니다. 따라서 유일한 방법은 char id를 52 bit Number로 변경하는 것입니다. 답변 주셔서 감사합니다. – Pan

+0

또는 클라이언트 쪽에서 문자열을 사용할 수 있습니다. – fsbmain

+1

@ 팬 이것이 도움이된다면 이것을 왜 대답으로 표시하지 않으시겠습니까? –