2012-02-08 3 views
3

두 개의 정수 변수 partialtotal이 있습니다. 진행 중이므로 partial이 0에서 시작하여 하나씩 total의 값으로 올라갑니다.두 개의 정수를 캐스팅하지 않고 두 배로 나누기

double fraction = double(partial)/double(total); 

을하지만 전체가 너무 큰 경우, 두배로 변환이 정보가 유실 될 수 있습니다 : 나는 진행을 나타내는 분수 값을 얻고 싶은 경우에

은 (1.0-0.0에서) 나는 다음을 수행 할 수 있습니다.

사실, 잃어버린 정보의 양은 용납 될 수 있지만 두 가지 값 사이의 분율을 줄이는 알고리즘이나 표준 기능이 있는지 궁금합니다.

+3

'double'은 53 비트 가수가 있습니다. '총'이> 53 비트 일 수 있다고 말하는가? –

+6

'partial'과'total'의 데이터 타입은 무엇입니까? IIRC는 'double'은 정확도의 손실없이 32 비트 정수를 저장할 수 있습니다. –

+1

글쎄,'total'은 십진수로 약 16 자리 숫자 인'> 2^53'의 값을 가져야합니다. 너무 큰 숫자가 있는지 궁금합니다. 이 경우에는 정수가 64 비트 너비가되기를 바랍니다. 그렇지 않으면 처음에는 충분하지 않습니다. –

답변

7

확실한 대답은 partial에 약간의 배율 인수를 곱한 것입니다. 100은 종종 백분율로 을 적분 값 (절사)으로 제공하므로 자주 선택해야합니다. 문제는 값이 이므로 매우 커서 double으로 표시 할 수없는 경우 이기 때문에 배율 인수를 곱한 값이 오버플로가 될 가능성이 있습니다. (그만큼 큰 경우 초기 값인 은 대부분의 컴퓨터에서 int을 오버플로합니다.)

0

분수의 정확한 표현을 원할 경우 분자를 포함하는 일종의 구조가 있습니다 그리고 분모를 정수로 사용하고, 고유 한 표현을 위해, 가장 큰 공약수 (0을 나타내는 특수한 경우)를 제외하면됩니다. 반복 연산 후에 부동 소수점 표현이 정확하지 않을까 걱정된다면, 그 문제는 프로그래밍 문제가 아니기 때문에 수치 해석에 대한 몇 가지 과정을 찾아야합니다. 특정 결과를 계산하는 다른 방법보다 나은 방법이 있지만, 실제로 들어갈 수는 없습니다. (필자는 교과서를 한번도 읽지 않고 그냥 읽었습니다.)

1

예, 정보가 손실되는 알고리즘이 있습니다. 분수의 수학적 값에 가장 가까운 double 값을 찾으려는 경우 total << 53을 보유 할 수있는 정수 유형이 필요합니다. 자신 만의 라이브러리를 만들거나 GMP와 같은 라이브러리를 사용할 수 있습니다. 그런 다음

  • 규모 partial 그래서 numerator = (partial << m)
  • q가 할 수 numerator/totalr = numerator % total
  • 정수 몫을하자 (total << 52) <= numerator < (total << 53), 그 mantissa = q, 2*r < total 경우 = q+1 당신이 절반을 반올림하려면 mantissa = q+1, 2*r > total 경우와 2*r == total 경우 , = q 반올림하려는 경우 두 반의 반올림을 원할 경우
  • result = scalbn(mantissa, -m)

당신이 (double)partial/(double)total에 같은 값을 얻을 때, 하나의 최하위 비트의 차이는 아마 두 개 또는 세 개의 LSB 차이 중 하나 나를 놀라게하지 않을 너무 드문 것은 아니지만, 드문있는 대부분의 더 큰 차이는 없을 것입니다 (즉, 누군가가 곧 예제를 제시 할 것입니다).

이제는 노력할 가치가 있습니까? 일반적으로 아닙니다.

관련 문제