2011-09-17 7 views
1

Geforce GTX 580 (Fermi)에서 CUDA 4.0을 사용하고 있습니다. 나는 7.721155e-43만큼 작은 숫자를 가지고있다. 7.721155e-43 * 7.721155e-43을 계산하기 위해 서로 곱 해보고 싶습니다.CUDA, 부동 소수점

내 경험에 비추어 볼 때 나는 그것을 곧바로 할 수 없다는 것을 보여주었습니다. 제게 제안 해 주시겠습니까? 배정 밀도를 사용해야합니까? 방법?

+4

난 당신이 몇 가지로 모든 계산을 확장 할 수 있습니다하지 않는 한,이를 위해 배정 밀도로 이동해야합니다 생각 적절한 요인? –

답변

5

가장 작은 일반 IEEE 단 정밀도 숫자의 크기는 약 1.18e-38이고, 가장 작은 비정규 성은 약 1.40e-45까지 내려갑니다. consequece로서 크기 7.82e-43의 피연산자는 단지 9 개의 0이 아닌 비트로 구성되며, 곱셈 (결과는 단 정밀도에서 0으로 언더 플로우)에 도달하기 전에도 그 자체로 이미 문제가 될 수 있습니다. 따라서 이러한 작은 숫자를 생성하는 업 스트림 계산을 살펴볼 수도 있습니다.

이 작은 숫자가 수학 표현의 중간 용어 인 경우 해당 표현식을 작은 중간체가 포함되지 않은 수학적으로 동일한 것으로 다시 작성하면 문제를 해결할 수 있습니다. 또는 2의 거듭 제곱 인 요소로 일부 피연산자의 비율을 조정할 수 있습니다 (배율 조정으로 인한 추가 반올림이 발생하지 않도록). 예를 들어 2^24 = 16777216으로 축척합니다.

마지막으로 계산의 일부를 배정도로 전환 할 수 있습니다. 그래서, 단순히 두 번 유형의 임시 변수를 소개 그들에 계산을 수행하려면 다음 떠 다시 최종 결과를 변환 :

통계에서
float r, f = 7.721155e-43f; 
double d, t; 

d = (double)f; // explicit cast is not necessary, since converting to wider type 
t = d * d; 
[... more intermediate computation, leaving result in 't' ...] 
r = (float)t; // since conversion is to narrower type, cast will avoid warnings 
0

우리는 종종 매우을 끝나게 우도와 함께 일해야 작은 숫자와 표준 기술은 모든 것을 위해 로그를 사용하는 것입니다. 로그 스케일에서의 곱셈은 단지 덧셈입니다. 모든 중간 번호는 로그로 저장됩니다. 사실 조금 익숙해 질 수 있습니다. 그러나 상대적으로 겸손한 계산을 할 때에도 대안이 실패하는 경우가 종종 있습니다. (! 내 편의를 위해) R 7 개 유효 숫자 BTW 기본적으로 복식과 인쇄를 사용에서 :

> 7.721155e-43 * 7.721155e-43 
[1] 5.961623e-85 
> exp(log(7.721155e-43) + log(7.721155e-43)) 
[1] 5.961623e-85