2012-10-10 7 views
0

부호없는 long long을 취하는 함수를 만들고, 삼각형이 둔각, 예각 또는 직각 삼각형인지 알아 내기 위해 코사인 법칙을 적용합니다. 변수를 사용하기 전에 변수를 double에 캐스팅해야합니까?이중으로 부호없는 long long 산술

void triar(unsigned long long& r, 
      unsigned long long x, 
      unsigned long long y, 
      unsigned long long z) 
{ 
    if(x==0 || y==0 || z==0) die("invalid triangle sides"); 

    double t=(x*x + y*y -z*z)/(2*x*y); 

    t=acos (t) * (180.0/3.14159265); 

    if(t > 90) { 
    cout<<"Obtuse Triangle"<<endl; 
    r=t; 

    } else if(t < 90){ 
    cout<<"Acute Triangle"<<endl; 
    r=t; 

    } else if(t == 90){ 
    cout<<"Right Traingle"<<endl; 
    r=t; 

    } 
} 
+0

왜 함수가'double '이 아닌'unsigned long long'을 사용합니까? – Troubadour

답변

2

부동 소수점 연산이 필요한 경우 캐스팅 할 수없는 이유는 일반적으로 없습니다. 그러나 unsigned long에서 double으로의 암시 적 변환도 있으므로 캐스팅하지 않고도 완전히 수행 할 수 있습니다.

당신을 포함하여 많은 경우에 하나의 인수 만 캐스팅하여 double 개의 연산을 특정 조작에만 적용 할 수 있습니다. 예를 들어,

이렇게하면 나누기를 제외한 모든 연산이 정수 연산에서 계산되므로 slighly 빠릅니다. 분할하는 동안 절단을 피하기 위해 캐스트가 필요합니다.

코드에 부동 소수점 인수의 비교가 포함되어 있습니다. 그러나 부동 소수점 연산은 정확성을 거의 필연적으로 감소시킵니다. 제한된 정확도를 피하거나 정확도를 분석하고 제어하십시오. 훌륭한 자매 대답에 설명 된대로 귀하의 처분 항상

  • 인간에게 프리젠 테이션을 제외하고 라디안에서 변환을 방지하기에 충분히 넓은 정수형이있는 경우

    • 는 정수에게 전용 솔루션을 선호

    • 수학 라이브러리 헤더 파일에서 π 값을 가져옵니다 (불행히도 이것은 플랫폼에 따라 다름 - _USE_MATH_DEFINES또는 이미 부스트 라이브러리를 사용중인 경우 boost::math::constants::pi<double>()) 또는 분석적으로 표현하십시오. 예를 들어, std::atan(1)*2은 직각입니다.

    • 배정도를 선택하고 궁극적 인 차이 값이 std::numeric_limits<double>::min() * 8보다 작 으면 삼각형에 대해 말할 수 없으며 반환하는 분류는 기본적으로 가짜입니다. (나는 당신이 가능하게 세보다 훨씬 더 많은 비트를 잃게됩니다, 8의 값을했다.)

      당신은 둔각 삼각형에 문제가
  • +0

    hmmm 이전에 시도했지만 작동하지 않았습니다. 이제 작업 ..... 잘 어쨌든 당신의 도움을 주셔서 감사합니다 :) – Painguy

    +0

    @ NimaGanjehloo - 그것이 작동하지 않았을 때 전체 사업부 주위에 여분의 괄호가 있다면 하나의 가능한 설명이 될 것입니다. 이 경우 잘린 결과를 캐스팅했을 것입니다. –

    1

    , x*x + y*y - z*z 수학적으로 (그 다음이다 모듈 2^WIDTH 감소 부정적인 결과를 줄 것이다 여기서 WIDTHunsigned long long의 값 비트 수, 적어도 64이며 아마도 정확하게는) - 아마 큰 양수 값 (드문 경우 0)을 산출합니다. 그러면 t = (x*x + y*y - z*z)/(2*x*y)의 계산 결과는 1보다 클 수 있으며 acos(t)은 NaN을 반환합니다.

    주어진 인수 유형으로 삼각형이 둔각/급경사/직각인지를 확인하는 올바른 방법은 x*x + y*y < /* >/== */ z*z인지 여부를 확인하는 것입니다. 수학 결과가 unsigned long long 범위를 초과하지 않는지 확인할 수 있습니다. 당신이 확신 할 수없는 경우

    , 당신은 거의 직각 삼각형에 대한 정밀도와 잘못된 결과의 가능한 손실, 계산하기 전에 double

    double xd = x, yd = y, zd = z; 
    double t = (xd*xd + yd*yd - zd*zd)/(2*xd*yd); 
    

    을 변수로 변환 할 수 있습니다 (예를 들어,약간 둔한 삼각형 x = 2^29, y = 2^56-1, z = 2^56+2의 경우 yz은 표준 64 비트 double을 사용하여 2^56으로 변환되고 xd*xd + yd*yd = 2^58 + 2^1122^112으로 계산되고 zd*zd을 빼면 0이됩니다.

    또는 정수 계산 만 사용하여 ~ z*z - 또는 x*x ~ z*z - y*y을 비교할 수 있습니다. x*xunsigned long long으로 표현 가능한 경우 (나는 0 < x <= y <= z이라고 가정 함) 상대적으로 쉽게 (z - y)*(z + y)ULLONG_MAX을 초과하는지 여부를 확인합니다. 그렇다면 삼각형이 둔감합니다. 그렇지 않으면 계산하고 비교하십시오. 만약 x*x이 표현 가능하지 않다면, 복잡해진다. (물론 큰 정수 라이브러리를 사용하는 것을 제외하고) 가장 쉬운 방법은 높이를 계산하고, 필요하다면 64 (또는 어떤 너비 가든 unsigned long long) 비트를 나누어서 계산하는 것이다. 너비의 절반에 해당하는 숫자를 비교하십시오.

    추가 참고 : π, 3.14159265에 대한 사용자의 값은 너무 정확하지 않으며 직각 삼각형은 둔각으로보고됩니다.

    +0

    +1 특히 π의 값에 대한 메모입니다. –