2012-04-15 4 views
1

입니다. 프로그램은 2x2 행렬에서 음수 요소의 평균 기하 평균을 계산합니다. 아래 프로그램에서 코드를 이해하려고 시도하고 있으며 작성자가 작성한 이유를 누군가가 설명 할 수 있습니다. 이 코드는 아래의 저자는 코드행렬의 기하 평균은

#include <stdio.h> 
#include <math.h> 

#define ROWS 2 
#define COLS 2 
char * last_geom_err = NULL; 

float geometricMean(float * arr, int rows, int cols){ 
    float neg_mul = 1; 
    int neg_count = 0; 
    float arr_elem; 
    for (int i = 0; i < rows; i++) 
     for (int j = 0; j < cols; j++) 
      if((arr_elem = *(arr + i * cols + j)) < 0){ 
       neg_mul *= arr_elem; 
       neg_count++; 
      } 
    if (neg_count == 0){ 
     last_geom_err = "no negative elements in array"; 
     return 0; 
    } 
    if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
     last_geom_err = "a negative number under the square root of even degree"; 
     return 0; 
    } 
    last_geom_err = NULL; 
    return pow(neg_mul, (float)neg_count); 
} 

int main(){ 
    float arr[ROWS][COLS] = { 
     1., -2., 
     -5., -6. 
    }; 
    printf("Array:\n"); 
    for(int i = 0; i < 2; i++){ 
     for(int j = 0; j < 2; j++) 
      printf("%5.2f ", arr[i][j]); 
     putchar('\n'); 
    } 
    float gm = geometricMean((float*)arr, ROWS, COLS); 
    if (last_geom_err != NULL) 
     printf("#Error of calculation: %s", last_geom_err); 
    else 
     printf("Geometric mean of negative elements of array = %5.2f", gm); 
    return 0; 
} 

이유에 너무 많은 포인터를 쓴 열심히 을 이해하기 위해 찾는 메신저는 무엇입니까?

char * last_geom_err = NULL; 

    float geometricMean(float * arr, int rows, int cols){ 
     float neg_mul = 1; 
     int neg_count = 0; 
     float arr_elem; 
     for (int i = 0; i < rows; i++) 
      for (int j = 0; j < cols; j++) 
       if((arr_elem = *(arr + i * cols + j)) < 0){ 
        neg_mul *= arr_elem; 
        neg_count++; 
       } 
     if (neg_count == 0){ 
      last_geom_err = "no negative elements in array"; 
      return 0; 
     } 
     if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
      last_geom_err = "a negative number under the square root of even degree"; 
      return 0; 
     } 
     last_geom_err = NULL; 
     return pow(neg_mul, (float)neg_count); 
    } 

이 하나

float gm = geometricMean((float*)arr, ROWS, COLS); 
     if (last_geom_err != NULL) 
      printf("#Error of calculation: %s", last_geom_err); 
     else 
      printf("Geometric mean of negative elements of array = %5.2f", gm); 
     return 0 
+0

을 NaN인지를 반환하는, 그러나

return pow(neg_mul, 1.0/neg_count); 

과 유사해야합니까 특히 당신은 이해하지 못합니까? 기본적인 C 구문을 이해하고 있습니까? –

+0

@MarkByers, 그것은 행렬이 평평한 메모리 내 표현으로 액세스되는 방식과 관련이 있습니다 ('(float **)'에서'(float *)'로의 캐스트를 참고하십시오). – geekosaur

+0

@geekosaur 당신이 바로 그거야. 내가 꽤 혼란스러워. –

답변

2

프로그램은 그렇지 × 2 행렬

마이너스 요소의 평균 기하 평균을 계산한다. 첫째, 대개 geometric mean applies only to positive numbers.입니다. 기하 평균 인 k을 음수로 다소 의미있는 방식으로 정의를 확장 할 수 있습니다. 음수는 절대 값의 기하 평균의 음수이지만 두 음수를 모두 포함하는 집합의 기하 평균 양수가 명확해야합니다. 기하 평균을 확장하는 또 다른 의미있는 방법은 홀 유사성 (holomorphy)의 도메인에 대한 홀 유사 (holomorphic) 기능으로서의 확장 일 것이다 (k > 1에 대해서는 k의 부분 집합이 아님). 여기에는 이전 확장 물이 ¸ k 위의 값으로 포함됩니다.

어쨌든 기하 평균의 계산에는 주어진 양식에 어떤 형태로든 k 번째 루트가 포함됩니다. 이제 코드를 살펴 보겠습니다. 음수 배열 요소 곱셈 및 그 카운트의 초기화.

float arr_elem; 
    for (int i = 0; i < rows; i++) 
     for (int j = 0; j < cols; j++) 

행렬의 메모리 레이아웃

 -------------------------------------------- 
arr -> | row 0 | row 1 | row 2 | ... | row (rows-1) | 
     -------------------------------------------- 

그래서 row 0가 0 cols - 1row 12*cols - 1cols은 일반적 row k는 슬롯을 (k+1)*cols - 1-k*cols 점유 슬롯을 점유 슬롯을 차지한다. 따라서 arr + i*cols + jcol j을 가리키며 row i을 가리 킵니다.

  if((arr_elem = *(arr + i * cols + j)) < 0){ 
       neg_mul *= arr_elem; 
       neg_count++; 
      } 

읽기 행렬 요소 a[i][j]하고 음수이면, 모든 음의 항목의 곱으로 곱으로 계산. 플랫 메모리 레이아웃으로 인해 for(k = 0; k < rows*cols; ++k)을 루프하고 arr[k]에 액세스 할 수 있습니다.

if (neg_count == 0){ 
     last_geom_err = "no negative elements in array"; 
     return 0; 
    } 

배열에 부정적인 요소가 전혀 포함되어 있지 않으면 오류 메시지를 설정하고 돌아옵니다. 숫자가없는 (기하학적) 평균은 전혀 의미가 없습니다.

if ((neg_count % 2 == 0) && (neg_mul < 0)){ 
     last_geom_err = "a negative number under the square root of even degree"; 
     return 0; 
    } 

음수 항목 수가 짝수이고 음수 항목이 음수이면 오류 메시지를 설정하고 돌아갑니다.

이것은 죽은 코드입니다. 짝수 개의 음수의 곱은 항상 양의 값이며 부동 소수점 산술 (IEEE 754에 부합하거나 충분히 근접한 경우에만 해당)에주의하십시오. 완전히 파손되면 아무 일도 발생할 수 없습니다. 언더 플로우이므로 수학적으로는 0이 될 수 있습니다. 그렇지 않습니다. (오버플로 여기에 문제가되지는 무한대는 0으로 비교하고 정상적으로 곱셈으로 동작합니다.)

last_geom_err = NULL; 
    return pow(neg_mul, (float)neg_count); 
} 

마지막으로, 어떤 예외적 인 상황이 발생하지 않기 때문에, NULL에 오류 메시지를 설정하고

을 반환

(음수 항목) (음수 항목 수)입니다.

기하 평균의 경우, 마지막 줄 neg_mul < 0pow 이후는 정수 지수에 대한 부정적인 기지를 처리하는 경우 그래서,

if (neg_mul < 0) { 
    return -pow(-neg_mul, 1.0/neg_count); 
} else { 
    return pow(neg_mul, 1.0/neg_count); 
}