2015-01-21 4 views
0

flooded 정수 구분 (예 : Python offers)을 C#으로 처리하는 것이 쉽고 효율적이며 (즉, 이중에서 /로 변환하지 않아야합니다.) 방법이 있습니까?플로팅 된 정수 나누기

즉, 장/이중 변환 손실이없는 다음의 효율적인 버전입니다.

(long)(Math.Floor((double) a/b)) 

또는 예를 들어,

static long FlooredIntDiv(long a, long b) 
{ 
    if (a < 0) 
    { 
     if (b > 0) 
      return (a - b + 1)/b; 
     // if (a == long.MinValue && b == -1) // see *) below 
     // throw new OverflowException(); 
    } 
    else if (a > 0) 
    { 
     if (b < 0) 
      return (a - b - 1)/b; 
    } 
    return a/b; 
} 

*) 내 시스템에 던져 (않는 현실에서 OverflowExceptionunchecked 내부에서 발생 leaves it open 여부를 나누기 연산자)와 Visual Studio .NET 2003 version의 C# 4 사양은 심지어 던져 의무 있지만 :

왼쪽 피연산자가 가장 작은 int 또는 long 값을 나타내고 오른쪽 피연산자가 -1 인 경우 [..] System.OverflowException은이 상황에서 작업이 확인 된 컨텍스트 또는 확인되지 않은 컨텍스트에서 발생하는지 여부에 관계없이 항상 발생합니다.

편집

checkedunchecked에 대한 그어 문이 아니라 모든 좋은,하지만 checkedcompile time concept, 그래서 여부 제 기능을 주위에 포장해야 사실입니다 또는 함수를 호출하는 코드가 checked 안에 있는지 여부에 관계없이 어쨌든 내게 달려있다.

+1

결과는'Math.Floor'에 결과를 전달하는 대신 사용할 수 있습니다. –

+0

정수 부분은 문자 그대로 Math.Floor를 호출하지 않고 이미이를 수행하고 있지만 결과는 동일하며 소수 부분 만 잘라 버립니다. 이 경우 Math.Floor는 중복됩니다. –

+1

@maremp : 긍정적 인 결과 만 나타냅니다. C#'/'연산자 구현과 다른 "floor"부정 결과의 예는 OP 표를 참조하십시오. –

답변

0

정상적인 작동 순서를 따르는 정상적인 프로그래밍 언어에서 작동하는 방식은 -1.0/3.0-(1.0/3.0) 인 것은 -0.3333...입니다. 그래서 그것을 int로 변환하기를 원한다면, 그것은 나누기가 아니라 생각할 필요가있는 캐스트/플로어 연산자입니다. 따라서이 동작을 원할 경우 (int)Math.Floor(a/b) 또는 사용자 지정 코드를 사용해야합니다.

+0

고마워, 나는 그 대답을 삭제했다. 전산 물리학에서 배웠던 몇 가지 개념은 오용으로 인해 손상되어 합리적이지 못한 방식으로 재결합되었습니다. :) 부동 소수점 부정확으로 인해 최소한의 정보를 잃어 버리는 것을 목표로 작업의 어떤 부분을 캐스팅해야하는지에 대한 규칙/지침이 있지만, 대학 이후 실제로 사용하지는 않았으므로 구체적인 내용은 잊어 버렸습니다. – piojo

1

이 작업을 시도 할 수 있습니다 :

if (((a < 0)^(b < 0)) && (a % b != 0)) 
{ 
    return (a/b - 1); 
} 
else 
{ 
    return (a/b); 
} 

편집 (아래 의견에 약간의 토론 후) :

경우 - 다른 사용하지 않고, 내가 같이 갈 것 :

return (a/b - Convert.ToInt32(((a < 0)^(b < 0)) && (a % b != 0))); 

참고 : Convert.ToIn32(bool value)도 점프가 필요합니다. 방법 중 implemention 참조 :

,515,
return value? Boolean.True: Boolean.False; 

이론적으로 예상 된 결과 a/b = abs(long.MinValue) = long.MaxValue + 1 > long.MaxValue 때문에, a = long.MinValueb = -1L 대한 분할을 계산하는 것은 불가능하다. (long의 범위는 –9,223,372,036,854,775,808에서 9,223,372,036,854,775,807입니다.)

+0

추 신 : ^는 xor 연산자입니다 – Bhaskar

+0

감사합니다 L16H7. 위의 'FlooredIntDiv'을 구현할 때 나는 효율적으로 솔루션과 비슷하게 시작 했으므로 (솔루션이 모든 '0'모서리의 경우를 포착했는지는 생각하지 못했습니다.) 'if/else' 경로는 읽기가 더 쉽다고 생각하기 때문에갔습니다. 따라서 샘플 구현과 동일하지만 더 쉽고 효율적이지 않습니다. –

+0

일반적으로 "효율적인"수식에는 "if"문 등을 사용하면 안됩니다. 그것은 순수하게 저수준 산술 연산자를 기반으로해야합니다. –