2010-08-08 4 views
7

이상한 버그를 해결할 때 도움이 필요합니다. x86에서 mod (%) 연산자를 사용하면 좋음, x64에서는 때때로 NaN이 나머지로 나타납니다 (일반적으로 Angle = 0). 나는 그 코드를 내 코드 외부에서 재현 할 수 있었지만 Angle = double 만 사용했다. 엡실론 (내 코드에서는 Angle = 0에서도 발생).x86 대 x64의 Mod (%) 연산자

class Program 
{ 
    public const double M_PI = 3.14159265358979323846; 
    static void Main(string[] args) 
    { 
     double m_2PI = (2 * M_PI); 
     double m_Angle = double.Epsilon; 
     double mod = (m_Angle % m_2PI); 
     //x86 mod = 4.94065645841247E-324 
     //x64 mod = NaN 
     if (double.IsNaN(mod)) 
      Debug.Write(mod); 
    } 
} 

감사합니다, 셰이

+0

버그가 확실하지 않습니다. x86 및 x64 부동 소수점은 다른 결과를 반환 할 수 있습니다. 그 문제를 해결하기 만하면됩니다. –

+1

작은 팁 : 자신의 상수로 지정하는 대신'Math.PI'를 사용할 수 있습니다 –

답변

1

이 이상한 버그, 오히려 아주 기대 버그가 아닙니다. 숫자 데이터 유형의 바깥 범위에 있고 작업과 함께 플레이하는 경우 이러한 일이 발생하지 않으면 놀랄 것입니다.

솔루션은 mod 함수를 캡슐화 할 수 있습니다.

static double myMod(double v, double m){ 
    if(v < m) return v; 
    return v % m; 
} 

나는 왜 그런 경계선 사건에 대해 걱정할 수 있습니까?

+7

분명히 경계선은 매우 중요합니다. 그들은 프로덕션 소프트웨어에서 많은 수의 버그를 설명합니다. –

+0

'v' 또는'm'이 음수 일 수있는 경우 주어진 함수가 올바르지 않습니다. – phoog

1

C#에서 계수 연산자는 일반적인 C의 int 값보다 많은 것을 취할 수 있습니다. 하지만 그래, 나는 당신이 엡실론 수량을하고있을 때 ISA의 차이점이 있다고 생각한다.

귀하의 경우에는 엡실론이 충분히 적으므로 NAN이 발생할 수 있습니다.

플로트 및 기타 유형으로 재현 할 수 있는지 확인하십시오. 당신이 그들을 사용할 수 있다면, 문제는 "해결"됩니다.

해결 방법은 엡실론 근처에서 직접 수학을 수행하고 0을 반환하면됩니다.

0

면책 조항 : .Net 프로그래머가 아닙니다.

그러나 이것은 버그처럼 들립니다. 제공된 입력에 대한 작업은 잘 정의되어 있으므로 m_Angle을 반환해야합니다. 내 생각에 구현은 무조건 입력을 위해 언더 플로우하는 m_Angle/m_2PI 디비전을 무조건 시도합니다. 분명히이 조건의 처리는 32 비트 플랫폼과 64 비트 플랫폼간에 다릅니다. 여분의 범위 검사를 위해 약간의 런타임 패널티가 드는 Marcus Johansson의 답변과 비슷한 것을 사용하여 올바르게 수행되었을 수 있습니다.