본문 바로가기

PROFILE/Independent project

Binary Decimal transferal - Dos based / C / Mar. 2008




#include <iostream>
#include <string>

using namespace std;

#define MAX 60

int factorial(int number,int jinsu,unsigned long long result);
int Two();
int Ten();

void main(){
RESTART:
cout << "\t\t┏━━━━━━━━━━━━━━━━┓"<<endl
<< "\t\t┃2진수 <==> 10진수 변환기입니다. ┃"<<endl
<< "\t\t┗━━━━━━━━━━━━━━━━┛"<<endl<<endl;
cout << "\t◎ 원하시는 작업의 번호를 입력하시고 엔터키를 눌러주세요.\n"<< endl
<< "\t1. 2진수를 10진수로 변환하기입니다.\n"<<endl
<< "\t2. 10진수를 2진수로 변환하기입니다.\n"<<endl
<< "\t3. 2진수 <==> 10진수 변환기를 종료합니다.\n"<<endl
<< "\t입력 : ";
int key;
cin >> key;
system("cls");
if(key!=1 && key!=2 && key!=3)
cout <<"\n\n<오류메세지1> 키를 잘못입력하셨습니다.\n\n"<<endl;
switch(key){
case 1:{
Two();
break;}
case 2:{
Ten();
break;}
case 3:{
exit(0);
break;}
}
system("pause");
system("cls");
goto RESTART;
}

int factorial(int number,int jinsu,unsigned long long result){ //  number (몇번이나)  , jinsu (얼마나), result(결과가될값 )
result= result * jinsu; // jinsu를 number만큼 제귀하여 곱해준다.
if(number != 1) factorial(number-1,jinsu,result); //들어온값이 1이 아니면 반복*2
if(number ==1){ //1이면 종료
return result;
}
}

int Two(){
cout << "\t\t┏━━━━━━━━━━━━━━━━┓"<<endl
<< "\t\t┃2진수 ==> 10진수 변환기입니다.  ┃"<<endl
<< "\t\t┗━━━━━━━━━━━━━━━━┛"<<endl<<endl;
cout << "\t◎ 값(0, 1, .) 으로 2진수를 입력해주세요.\n"<<endl
<< "\t입력범위 : 정수 30자리, 소수 20자리까지입니다.\n"<< endl
<< "\t최대값:111111111111111111111111111111.11111111111111111111\n"<<endl
<< "\t입력 : ";

char inputbuff[MAX]; // 입력된값을 받을 곳
cin >> inputbuff;
cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
char* token,cLeft[MAX],cRight[MAX]; // 끊어준값을 임시저장할 버퍼, 문자형으로 저장할 정수,소수
unsigned long long iLeft=0,ibLeft,result=1; // 정수자리를 저장할 값과 버퍼
unsigned long double iRight=0,ibRight; // 소수 자리를 저장할 값과 버퍼
int LeftCount=0,Count=0,RightCount=0;
int val; //  펙토리얼을 사용하기 위한 결과값 선언
token = strtok( inputbuff, "." ); // 점까지 끊어서 저장
sprintf( cLeft, "%s", token ); // token 버퍼를 cLeft로 저장
token = strtok( NULL, " " ); // 끊어진부분부터 " " 까지 끊어서 버퍼에 저장
sprintf( cRight, "%s", token ); // token 버퍼를 cRight에 저장

//정수부분!
while(cLeft[Count]){
if(cLeft[Count]!='1' & cLeft[Count]!='0'){
cout <<"\n\n<오류메세지1> 키를 잘못입력하셨습니다.0과1을사용하지않은오류\n\n“<<
“ 메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
Count=Count+1;
}
if(Count>30){ // 30자리까지 정수형 처리 (오버플로 방지)
cout <<"\n\n<오류메세지2> 오버플로우. 너무 큰 정수를 입력하셨습니다.\n\n 메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
while(cLeft[LeftCount]){
char pLeft=cLeft[LeftCount];
char* ppLeft=&pLeft;
ibLeft=atoi(ppLeft); // 문자형을 int 형 버퍼에 넣음
val=factorial(Count--,2,result); // 2진수로 최종자리수 만큼의 곱을 val 에 넣음
iLeft=iLeft+(ibLeft*val/2); // iLeft에 자리수의 곱을 넣어서계산된 값을 iLeft에 넣음
if(Count!=1){
if(cLeft[LeftCount]==1)
iLeft=iLeft+1;
}
LeftCount=LeftCount+1;
}
cout << "\n\t\t정수부분의 값은 " << iLeft<< " 입니다." << endl;

//소수부분
for(int i =0;cRight[RightCount]=='0' || cRight[RightCount]=='1' || cRight[RightCount]=='.' ;i++){ // 소수점 20자리까지(오버플로방지)나 값이있을때까지 반복한다.21이넘으면 1로처리되기때문에
if(cRight[RightCount]=='.'){
cout <<"\n\n<오류메세지1> 키를 잘못입력하셨습니다.소수점을 두개이상사용한오류\n\n “<<
”메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
char pRight=cRight[RightCount];
char* ppRight=&pRight;
ibRight=atoi(ppRight);
val=factorial(++RightCount,2,result);
iRight=iRight+(ibRight/val);
if(i>=20){ // 20자리까지 th수형 처리 (언더플로 방지)
cout <<"\n\n<오류메세지2> 언더플로우. 너무 작은소수를 입력하셨습니다.\n\n“<<
“ 메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
}
cout << "\n\t\t소수부분의 값은 " << iRight << " 입니다." << endl;
cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
printf("\n\t\t\t\t10진수로 변환된 값은 : %f 입니다.\n\n", iLeft+iRight);
return 0;
}

int Ten(){
cout << "\t\t┏━━━━━━━━━━━━━━━━┓"<<endl
<< "\t\t┃10진수 ==> 2진수 변환기입니다.  ┃"<<endl
<< "\t\t┗━━━━━━━━━━━━━━━━┛"<<endl<<endl;
cout << "\t◎ 값 10진수를 입력해주세요.\n"<<endl
<< "\t입력범위 : 정수 1073741824, 소수 11자리까지입니다.\n"<< endl
<< "\t최대값:1073741824.99999999999\n"<<endl
<< "\t입력 : ";
char inputbuff[MAX];
cin >> inputbuff;
cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
char* token,cLeft[MAX],cRight[MAX];
unsigned long long iLeft=0,ibLeft,val,result=1;
float iRight=0,ibRight;
int LeftCount=0,Count=0,RightCount=0;

token = strtok( inputbuff, "." ); // 끊어서
sprintf( cLeft, "%s", token ); // 소수점 왼쪽 문자형
token = strtok( NULL, " " ); // 끊어서
sprintf( cRight, "%s", token ); // 소수점 오른쪽 문자형

// 정수부분
while(cLeft[LeftCount]){ // 정수부분에 값이 있으면 반복.
LeftCount=LeftCount+1; // LeftCount라는 정수부분의 자릿수 유추
}
ibLeft=atoi(cLeft); // 문자형을 정수형으로

if(ibLeft>1073741824){ //정수의 범위를 넘으면 에러처리
cout<< "\n\n<오류메세지2>오버플로우. 너무 큰 정수형을 입력하셨습니다.\n\n 메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
char str[MAX];
itoa(ibLeft,str,2); // ibLeft진수형을 str문자형포인터에 2진수로 변환한값을 넣으라는함수 
cout << "\n\t\t정수부분의 값은 " << str<< " 입니다." << endl; // str에는 10진수를 2진수로 변환한 char형값이 들어있다.

//소수부분 
while(cRight[RightCount]){ // 위와같이 자리수를 뽑아내기위해 반복
if(cRight[RightCount]=='.'){
cout <<"\n\n<오류메세지1> 키를 잘못입력하셨습니다.소수점을 두 개이상사용한오류\n\n“<<
“메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}

RightCount++; // RightCount는 입력된소수부분의 자리수
}
if(RightCount>11){
cout <<"\n\n<오류메세지2> 언더플로우. 너무 작은소수를 입력하셨습니다.\n\n 메인화면으로 다시 돌아가겠습니다."<<endl<<endl;
return 0;
}
ibRight=atoi(cRight); // 문자형을 실수형으로 만듦
val=factorial(RightCount,10,result); // RightCount(자리수) 만큼 10을 곱하는 자작 함수
ibRight=ibRight/val; // val은 factorial에서 반납된 값(자리수만큼 반복되어나온값)   ibRight는 그값을
for(int i=0;ibRight!=0&&i<=11;i++){ // 값이 0일때까지 반복 && 소수점 11자리까지(오버플로처리)

ibRight=ibRight*2;
if(ibRight>=1){
ibRight=ibRight-1; // 1보다클때만 1표시
iRight=iRight+1/((unsigned long double)result*10);
result=result*10; 
}
cout << "\n\t\t소수부분의 값은 " << iRight << " 입니다." << endl;
cout << "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";

char LeftCharBuff[30]; // 큰 수를 표시하기 위해 범위의제한이 없는 문자형으로 변경하는 절차임
char* pLeft=LeftCharBuff;
sprintf(pLeft, "%f",iRight); // 정수형을 문자형의 포인트에 집어넣음
char bchar[30]={0};
for(int i=0;LeftCharBuff[i];i++){ // 소수점 표시를 제거해서 다시 집어넣음 소수형에 0.01212로저장되있기때문
bchar[i]=LeftCharBuff[i+2];
}
printf("\n\t10진수로 변환된 값은 : %s.%s 입니다.\n\n", str,bchar); // 넓은 범위표시를 위해 문자형으로 변경하여 표시함
return 0;
}
// 에러처리를 위해 라인수가 2배 이상 늘었고
// c++에서 제공하는 진수변경 라이브러리를 사용하지 않았으며
// 직접 진수변경의 계산을 하면서 프로그램을 짜봤습니다.
// 인터넷과 책, 다른 소스는 일체 참조하지 않았으므로 만약 같은 소스를 발견하신다면 F를 주셔도 무방합니다.
// win API나 부가적 음수처리와 보수처리는 요구한 바가 아니므로 추가하지 않았지만 만약 부족하다면 즉시 추가 처리하겠습니다.
// 소스는 거의 대부분이 계산에 의한 처리이므로 다소 수학적으로 이해하기 어려울 수도 있으나 주요소스라인은 40라인 이내로 간단합니다.