분류 | 게시판 |
베스트 |
|
유머 |
|
이야기 |
|
이슈 |
|
생활 |
|
취미 |
|
학술 |
|
방송연예 |
|
방송프로그램 |
|
디지털 |
|
스포츠 |
|
야구팀 |
|
게임1 |
|
게임2 |
|
기타 |
|
운영 |
|
임시게시판 |
|
일반적인 큰정수 곱셈을 코딩했는데 이상한답이 나오네요.....지적질과 칼질 부탁드립니다.....
///////////////////////////////
///1.일반적인 큰 정수의 계산법///
///////////////////////////////
/*큰 정수 계산법 : 1. 큰 수를 담기위해 배열을 선언한다 그리고 인덱스가 큰배열로 제일큰 자릿수가 오도록 저장한다. ex(123456 => s[6][5][4][3][2][1]=123456)
2. 부호를 담기위한 int형을 선언한다.
3. (1,2)를 묶어서 Large_Integer형을 만든다. */
#include <stdio.h>
#include <stdlib.h>
#define DIGIT 100 // 최대한도 자릿수를 100자리까지 잡는다.
typedef struct large_integer// Large_Integer형
{
char n[DIGIT]; //저장시 숫자는 순서가 거꾸로 저장된다.
int p; //양수 음수 판단.(true=음수 .false = 양수)
} LARGE_INTEGER;
char i_a(int a); //정수를 알파벳으로 변환
int a_i(char a); //알파벳을 정수로 변환
int Digit_Count(LARGE_INTEGER x); //입력한 수가 몇자리인지를 구하는 함수.
void Initial(LARGE_INTEGER &x); // 배열을 초기화
void Input_num(LARGE_INTEGER &x, LARGE_INTEGER &y); // 숫자입력.
void Print_num(LARGE_INTEGER x); // 이용자가 보기 편하게 거꾸로 저장된 LARGE_INTERGER를 올바르게 출력.
void Reverse(LARGE_INTEGER &u); // 배열의 순서를 뒤집어준다.
void JudgePlusMinus(LARGE_INTEGER &u); //음수 양수를 판단해서 bool에 저장해준다.
LARGE_INTEGER CheckDigit(LARGE_INTEGER u); //0을 없애준다.
LARGE_INTEGER Mul_Usual (LARGE_INTEGER u, LARGE_INTEGER v); // 일반적 방법으로 두 수 곱하기
void main()
{
LARGE_INTEGER u, v, x;
Initial(u); Initial(v); Initial(x);
// u.v,x를 초기화해줍니다.
printf("첫번쨰 큰수 곱셈법\n");
Input_num(u, v);
//입력 및 배열에 거꾸로 저장
JudgePlusMinus(u); JudgePlusMinus(v);
//음수 양수를 판단해서 저장
printf("\n일반적인 곱셈법 : ");
Print_num(Mul_Usual(u,v));
}
int Digit_Count(LARGE_INTEGER x) // 자리수 구하기
{
int counter=0; //자릿수를 세기위한 counter 변수
for(int i=0 ; i<=DIGIT-1 ; i++) // 배열에서 NULL 이 나올때까지 루프돌려서 자리수를 알아낸다.
{
if(x.n[i] != NULL)
counter++;
else
break;
}
return counter;
}
void Initial(LARGE_INTEGER &x) // 배열을 초기화.
{
for(int i=0 ; i<=DIGIT-1 ; i++)
{
x.n[i] = 0; // 모든 배열에 0을 넣어준다.
}
x.p = 0; // 부호의 기본값을 양수로 설정.
}
void Input_num(LARGE_INTEGER &x, LARGE_INTEGER &y) // 입력받고 음수양수 처리 및 배열 거꾸로 돌려 저장
{
scanf("%s %s", x.n, y.n);
Reverse(x);
Reverse(y);
}
void Print_num(LARGE_INTEGER x) // 거꾸로 돌리고 출력
{
Reverse(x);
if(x.p == 1)
printf("- %s",x.n);
else
printf(" %s",x.n);
}
void Reverse(LARGE_INTEGER &u) // 배열에 저장된 숫자를 거꾸로 되돌리기 and 음수 양수 저장
{
int digit = Digit_Count(u);
char temp[DIGIT];
for(int i = 0 ; i<digit ; i++) //거꾸로 temp배열에 저장
temp[i] = u.n[digit-i-1];
for(int i = 0 ; i<digit ; i++)
u.n[i] = temp[i];
}
void JudgePlusMinus(LARGE_INTEGER &u) //양수 음수를 판단하여 0.1을 저장
{
int digit = Digit_Count(u);
if( u.n[(digit)-1] == '-')
{
u.p = 1; //음수
u.n[(digit)-1]=NULL;
}
else
u.p = 0; //양수
}
LARGE_INTEGER Mul_Usual(LARGE_INTEGER u, LARGE_INTEGER v) // 일반적 방법으로 두 수 곱하기
{
LARGE_INTEGER result;
Initial(result);
int carry1=0;
int carry2=0;
int digit1 = Digit_Count(u);
int digit2 = Digit_Count(v);
int digit3 = digit1+digit2;
result.n[digit3+1]=NULL;
Reverse(u);
Reverse(v);
for(int i=digit1 -1;i>=0;i--)
{
int k=digit1+i;
for(int j=digit2-1; j>=0; j--,k--)
{
if(a_i(u.n[i]) * a_i(v.n[j]) >=10) //u와 v의 한자리 배열의 곱이 carry를 발생시킬떄
{
carry1 = a_i(u.n[i]) * a_i(v.n[j]) / 10; //carry를 구해서 carry1에 저장
if( ( a_i(u.n[i]) * a_i(v.n[j]) % 10 + carry2 + a_i(result.n[k]) ) >=10 ) //전 단계 carry + 배열곱셈의 나머지 + 결과배열 기존값의 합이 carry를 발생시킬떄
{
carry1 = carry1 + ( (a_i(u.n[i]) * a_i(v.n[j]) % 10 + carry2 + a_i(result.n[k]) ) / 10 ); // 기존 carry에 덧셈으로 인해 증가하는 carry값을 더함.
result.n[k] = i_a( ( a_i(u.n[i]) * a_i(v.n[j]) % 10 + carry2 + a_i(result.n[k])) % 10 ); //해당 결과 배열에 carry하는 값을 뺸 나머지를 저장.
carry2 = carry1; //다음 연산시 carry를 더하기위한 대입.
}
else
{
result.n[k] = i_a(a_i(u.n[i]) * a_i(v.n[j]) % 10 + carry2 + a_i(result.n[k])); //더하기로 carry가 없기떄문에 그냥 나머지를 저장.
carry2=carry1; //다음 연산시 carry를 더하기위한 대입.
}
}
else
{
carry1 = 0; //곱으로 인한 carry가 발생하지 않으므로 carry값은 0이다.
if( ( a_i(u.n[i]) * a_i(v.n[j]) + carry2 + a_i(result.n[k]) ) >=10 ) //전 단계 carry + 배열곱셈의 나머지 + 결과배열 기존값의 합이 carry를 발생시킬떄
{
carry1 = carry1 + ( ( a_i(u.n[i]) * a_i(v.n[j]) + carry2 + a_i(result.n[k]) ) /10 ); //기존 carry에 덧셈으로 인해 증가하는 carry값을 더함.
result.n[k] = i_a( ( a_i(u.n[i]) * a_i(v.n[j]) + carry2 + a_i(result.n[k])) % 10 ); //해당 결과 배열에 carry하는 값을 뺸 나머지를 저장.
carry2 = carry1; //다음 연산시 carry를 더하기위한 대입.
}
else
{
result.n[k] = i_a( a_i(u.n[i]) * a_i(v.n[j]) + carry2 + a_i(result.n[k]) ); //해당 결과 배열에 carry하는 값을 뺸 나머지를 저장.
carry2 = carry1; //다음 연산시 carry를 더하기위한 대입
}
}
}
result.n[k-1] = i_a( a_i(result.n[k-1]) + carry2 ); //for문안에서 못 계산한 carry를 계산.
carry2 = 0; //자릿수 계산이 완료햇기 떄문에 0으로 초기화
}
Reverse(result);// 뒤집어서 저장
result=CheckDigit(result); //자리수 조정
return result; //결과 리턴
}
LARGE_INTEGER CheckDigit(LARGE_INTEGER u) // 배열 제일 오른쪽 큰 자리수가 0일 때 자리수 조정하기(EX : 123000 -> 123 )
{
LARGE_INTEGER result;
int digit = Digit_Count(u);
result = u;
for( int i = digit-1 ; i>0 ; i--)
{
if(result.n[i] == '0')
result.n[i] = NULL;
else break;
if(result.n[i-1] != '0')
break;
if(i == 1 || result.n[0] == '0')
result.n[1] = NULL;
}
return result;
}
int a_i(char a)
{
int re=0;
re=a-48;
return re;
}
char i_a(int a)
{
int re=0;
re=a+48;
return re;
}
죄송합니다. 댓글 작성은 회원만 가능합니다.
번호 | 제 목 | 이름 | 날짜 | 조회 | 추천 | |||||
---|---|---|---|---|---|---|---|---|---|---|
62 | 나도 모르겟다 랜덤 움직이는 짤~ [2] ![]() |
광야의어린싹 | 12/11/20 23:56 | 142 | 2 | |||||
▶ | 컴게의 코딩의신님들 저좀 도와주세요... [5] | 광야의어린싹 | 12/11/07 05:04 | 67 | 0 | |||||
60 | 제 2의 임재범이 나타났다!! [1] ![]() |
광야의어린싹 | 12/10/17 14:15 | 438 | 2 | |||||
59 | 초등학생 창의력 甲 [6] ![]() |
광야의어린싹 | 12/10/16 21:04 | 456 | 11 | |||||
58 | 어머 ! 여기서 이러시면 안되요~ [3] ![]() |
광야의어린싹 | 12/10/16 20:58 | 305 | 7 | |||||
57 | 순발력甲 [7] ![]() |
광야의어린싹 | 12/10/16 20:43 | 397 | 11 | |||||
56 | 제가 롤 개초보라 그런데 질문좀.. [4] | 광야의어린싹 | 12/10/14 15:02 | 137 | 1 | |||||
55 | 거기 목말라보이는 자네~ [5] ![]() |
광야의어린싹 | 12/10/09 16:18 | 136 | 6 | |||||
54 | 자네~ 목마르면.. ![]() |
광야의어린싹 | 12/10/09 15:07 | 158 | 0 | |||||
53 | 보지 않았어야 했는데... [6] ![]() |
광야의어린싹 | 12/09/18 00:53 | 341 | 11 | |||||
52 | 무기 나눔이요~ [7] ![]() |
광야의어린싹 | 12/06/20 21:45 | 432 | 1 | |||||
51 | 좋은건 아니지만 갓 60 찍은 님들 쓰실만한거 나눔 해요~ [13] ![]() |
광야의어린싹 | 12/06/20 17:25 | 482 | 1 | |||||
50 | 경매자 저만 안되나요? [1] | 광야의어린싹 | 12/06/20 11:18 | 97 | 0 | |||||
49 | 엉엉시벌 | 광야의어린싹 | 12/06/17 11:45 | 74 | 0 | |||||
48 | 이런 망할 경매장... [1] | 광야의어린싹 | 12/06/17 11:34 | 221 | 0 | |||||
47 | 매찬 세트 얼마쯤에 살수있어요? [1] | 광야의어린싹 | 12/06/17 10:35 | 147 | 0 | |||||
46 | 무료 나눔 합니다2 (역시 좋은건 아니예요) [1] ![]() |
광야의어린싹 | 12/06/17 03:37 | 323 | 0 | |||||
45 | 나눔 합니다(그리 좋은건 아니예요) [9] ![]() |
광야의어린싹 | 12/06/17 01:40 | 421 | 1 | |||||
44 | 지옥 엑2꺠실분 | 광야의어린싹 | 12/06/12 17:53 | 65 | 0 | |||||
43 | ㅋㅋㅋ으아 디아 멋지다!! ㅋㅋㅋㅋ [1] | 광야의어린싹 | 12/06/10 19:49 | 469 | 0 | |||||
42 | 아 진짜 짜증남 [1] | 광야의어린싹 | 12/06/09 16:00 | 149 | 0 | |||||
41 | 오유인이 여는 지옥 포니방없나요? ㅋㅋ [3] | 광야의어린싹 | 12/06/09 13:23 | 158 | 0 | |||||
40 | 만렙 법사 장비 도와주세요~ [8] | 광야의어린싹 | 12/06/09 09:42 | 141 | 0 | |||||
39 | 헬 엑트4 디아까지 잡아주실분!! | 광야의어린싹 | 12/06/08 21:07 | 38 | 0 | |||||
38 | 헬 엑4 꺠주시분!! | 광야의어린싹 | 12/06/08 20:46 | 56 | 0 | |||||
37 | 염치없지만 헬 엑4 디아까지 잡아주실분!!! | 광야의어린싹 | 12/06/08 20:36 | 79 | 0 | |||||
36 | 헬 3장 시작 55 법사 도와주실분.... | 광야의어린싹 | 12/06/08 18:18 | 52 | 0 | |||||
35 | 헬 엑2 55법사 세팅좀 해주실분 [1] | 광야의어린싹 | 12/06/08 18:10 | 73 | 0 | |||||
34 | 시벌 디아 드럽다 ㅠㅠ [3] | 광야의어린싹 | 12/06/08 17:51 | 275 | 0 | |||||
33 | 디아3 헬1엑트중간부터 꺠주실분.... | 광야의어린싹 | 12/06/06 22:06 | 45 | 0 | |||||
|
||||||||||
[1] [2] [3] [4] [5] | ||||||||||