[C언어] -0이 표시되는 이유와 없애는 방법 좀 알려주세요 ㅠㅠ
![익명 사용자의 이미지 익명 사용자의 이미지](/files/bluemarine_logo.png)
#include
int main(void)
{
int a[3][3], b[3][3], c[3][3], d[3][3];
int i, j, k;
float detA, invA[3][3];
printf("행렬 A 입력\n");
for (i = 0; i < 3; i++) //첫번째 행렬 입력
{
printf("%d행 => ", i + 1);
for (j = 0; j < 3; j++)scanf_s("%d", &a[i][j]);
}
printf("행렬 B 입력\n");
for (i = 0; i < 3; i++) //두번째 행렬 입력
{
printf("%d행 => ", i + 1);
for (j = 0; j < 3; j++)scanf_s("%d", &b[i][j]);
}
printf(" %d %d %d %d %d %d\n", a[0][0], a[0][1], a[0][2], b[0][0], b[0][1], b[0][2]);
printf("A = %d %d %d B = %d %d %d\n", a[1][0], a[1][1], a[1][2], b[1][0], b[1][1], b[1][2]);
printf(" %d %d %d %d %d %d\n", a[2][0], a[2][1], a[2][2], b[2][0], b[2][1], b[2][2]);
printf("----------------------\n");
for (i = 0; i < 3; i++) //행렬의 합 계산
{
for (j = 0; j < 3; j++)
c[i][j] = a[i][j] + b[i][j];
}
for (i = 0; i < 3; i++) //합의 결과 출력
{
for (j = 0; j < 3; j++)
{
if (i == 1 && j == 0)
printf("A + B = %d", c[i][j]);
else if (j == 0 && (i == 0 || i == 2))
printf(" %d", c[i][j]);
else
printf(" %d", c[i][j]);
}
printf("\n");
}
printf("--------------\n");
for (i = 0; i < 3; i++) //행렬의 곱 계산
{
for (j = 0; j < 3; j++)
{
d[i][j] = 0;
for (k = 0; k < 3; k++)
{
d[i][j] += a[i][k] * b[k][j];
}
}
}
for (i = 0; i < 3; i++) //곱의 결과 출력
{
for (j = 0; j < 3; j++)
{
if (i == 1 && j == 0)
printf("A * B = %d", d[i][j]);
else if (j == 0 && (i == 0 || i == 2))
printf(" %d", d[i][j]);
else
printf(" %d", d[i][j]);
}
printf("\n");
}
printf("--------------\n");
/*역행렬 계산*/
detA = a[0][0] * a[1][1] * a[2][2] - a[0][0] * a[1][2] * a[2][1]
+ a[0][1] * a[1][2] * a[2][0] - a[0][1] * a[1][0] * a[2][2]
+ a[0][2] * a[1][0] * a[2][1] - a[0][2] * a[1][1] * a[2][0];
invA[0][0] = (1 / detA) * (a[1][1] * a[2][2] - a[1][2] * a[2][1]);
invA[0][1] = (1 / detA) * (a[0][2] * a[2][1] - a[0][1] * a[2][2]);
invA[0][2] = (1 / detA) * (a[0][1] * a[1][2] - a[0][2] * a[1][1]);
invA[1][0] = (1 / detA) * (a[1][2] * a[2][0] - a[0][1] * a[2][2]);
invA[1][1] = (1 / detA) * (a[0][0] * a[2][2] - a[0][2] * a[2][0]);
invA[1][2] = (1 / detA) * (a[0][2] * a[1][0] - a[0][0] * a[1][2]);
invA[2][0] = (1 / detA) * (a[1][0] * a[2][1] - a[1][1] * a[2][0]);
invA[2][1] = (1 / detA) * (a[0][1] * a[2][0] - a[0][0] * a[2][1]);
invA[2][2] = (1 / detA) * (a[0][0] * a[1][1] - a[0][1] * a[1][0]);
for (i = 0; i < 3; i++) //역행렬의 결과 출력
{
for (j = 0; j < 3; j++)
{
if (i == 1 && j == 0)
printf("A^-1 = %.0f", invA[i][j]);
else if (j == 0 && (i == 0 || i == 2))
printf(" %.0f", invA[i][j]);
else
printf(" %.0f", invA[i][j]);
}
printf("\n");
}
return 0;
}
자료형 선언의 문제인가요? double, long double도 해봤는데
역행렬을 구하는 과정에서 자꾸 -0 이 나오네요ㅠㅠ
원인과 해결방법이 궁금합니다!
힌트
리눅스에서
했더니
scanf_s
모르겠다고 하네요.
kldp 에서는 소스코드는 code 로 감싸야 들여쓰기 안 깨집니다.
더하기 곱하기는 잘 되나요?
detA가 0일 때는 어떻게 되죠?
https://en.wikipedia.org/wiki/Signed_zero 참고하시고.
질문을 잘 정리하다보면 답에 가까이 갈 수 있을 겁니다.
세벌 https://sebuls.blogspot.kr/
gdb 로 한단계씩 실행해 보세요.
gdb 로 한단계씩 실행해 보세요.
이럴때 쓰라고 gdb 가 있는건데.
C 는 gdb 사용하지 않고는 제대로 하기 어려워요.
ieee754 부동소수점 형식에서 음수를 표기하는
ieee754 부동소수점 형식에서 음수를 표기하는 방식에 따른 artifact입니다.
아시겠지만, ieee754 부동소수점 형식은 수를 "부호 비트" + "절대값"으로 나타내지요.
그런 구조에서는 어쩔 수 없이 0을 두 가지 표현으로 나타낼 수 있게 됩니다: +0과 -0.
게다가, 연산 결과로서 -0이 나오는 경우를 허용함으로써, 부동소수점 연산을 조금이나마 더 간단하게 구현할 수 있는 경우가 있어요.
아래와 같은 경우를 보시길.
https://ideone.com/MQS7ft
뭐, 어쨌거나 틀린 결과는 아니지 않습니까?
+0이 -0과 같다는 걸 우리도 알고 컴퓨터도 아는 걸요.
꼭 그렇게 박멸해야겠다고 생각하시는 이유를 잘 모르겠습니다. 그냥 보기 싫어서 그런가요?
https://ideone.com/JbQMme
https://ideone.com/JbQMme
+0, -0 이 다르다고 판단해야 하는 경우는 memcmp() 를 사용해야겠네요...
그것도 방법입니다.
그것도 방법입니다.
확인하신 것과 같이, 바이트열 레벨에서는 +0.0과 -0.0이 분명 다르니까요. 부호 비트 하나 차이입니다만.
C99부터는 좀 더 명시적인 방법으로 구분할 수도 있습니다. 아래 코드를 보시죠.
실행 결과: https://ideone.com/Rmo5LQ
댓글 달기