김성진 님이 쓰신 글 :
: int로 변수를 설정하여.. 어레이로 저장할꺼거든요
: 15자리의 숫자를 어레이 두개로 나누어 저장할려하는데
: 문제는 이걸 나누기 연산을 해야 하는데요..
: 어케 해야하는지좀 가르쳐 주세요...
터보C이면 __int64가 안 되겠죠?
된다면 십진수 20자리까지는 될텐데...
안 된다면 처음 나눗셈 배울 때 처럼 int 두 개를 다루어야겠죠.
2원소 배열에서 각각의 원소를 한 자리로 보고 나눗셈을 하는 루틴을 만들어야 하지 않을까요...
예를 들어, 10진수 나눗셈을 할 때 26/35 하면 각 자리(1의자리, 10의자리)가 있잖아요.
그렇듯 int 배열의 두 원소를 각각 한자리로 보고 26/35를 손으로 써가며 계산할 때 사용하는 방식을 프로그램으로 옮기면 될듯한데요....
SelfType& SubstractBase(UIndexType idx,const DoubleElementType& val)
{
DoubleElementType n1;
ElementType n2;
for(UIndexType i=idx ;i<idx+2&&i<ElementCount ;++i)
{
n1=Elements[i];
n2=val>>((i-idx)*ElementTypeBitCount);
if(n1<n2) n1+=Borrow(i+1);
Elements[i] = n1 - n2;
}
return *this;
}
SelfType operator / (const SelfType& dvs) const
{
SIndexType divisorMsbIdx = dvs.GetMSBIndex();
if(divisorMsbIdx<0) throw std::runtime_error("Divide by zero");
//else if(ElementCount==2) return SelfType(operator DoubleElementType()/(DoubleElementType)dvs);
//else if(ElementCount==1) return SelfType(operator ElementType()/(ElementType)dvs);
//else if(divisorMsbIdx==0 && dvs.Elements[0]==1) return *this;
SelfType dividend(*this),divisor(dvs);
int sign1=Absolute(dividend),sign2=Absolute(divisor);
divisorMsbIdx = divisor.GetMSBIndex();
if(divisorMsbIdx==0 && divisor.Elements[0]==1)
{
if(sign1!=sign2) ComplementOfTwo(dividend);
return dividend;
}
SelfType ret;
SIndexType dividendMsbIdx = dividend.GetMSBIndex();
if(dividendMsbIdx<0 || dividendMsbIdx<divisorMsbIdx) return ret;
else if(dividendMsbIdx==divisorMsbIdx && Elements[dividendMsbIdx]<divisor.Elements[divisorMsbIdx]) return ret;
SelfType rdividend;
UDElementType num,share;
// ElementType share;
SIndexType rdividendIdx,dividendIdx,subDividendIdx;
SIndexType divisorIdx,rdivisorIdx,retIdx;
dividendIdx = dividendMsbIdx;
retIdx = dividendMsbIdx-divisorMsbIdx;
for(; dividendIdx>=0&&retIdx>=0 ;--retIdx)
{
for(divisorIdx=divisorMsbIdx; dividendIdx>=0&&divisorIdx>=0&&retIdx>=0 ;)
{
if(dividendIdx<dividendMsbIdx)
num = ((UDElementType)dividend.Elements[dividendIdx+1])<<ElementTypeBitCount;
else num=0;
num += (UDElementType)dividend.Elements[dividendIdx];
share = num / divisor.Elements[divisorIdx];
if(0!=share)
{
rdividend=dividend;
ret.Ceil(retIdx,(UElementType)share);
ret.Ceil(retIdx+1,(UElementType)(share>>ElementTypeBitCount));
//ret.Elements[retIdx]=share;
dividend.SubstractBase(dividendIdx,share*(DoubleElementType)divisor.Elements[divisorIdx]);
--dividendIdx;
subDividendIdx = dividendIdx;
rdividendIdx = dividendIdx;
--divisorIdx;
rdivisorIdx = divisorIdx;
break;
}
ret.Elements[retIdx--]=0;
--dividendIdx;
}
for( ; divisorIdx>=0&&subDividendIdx>=0&&retIdx>=0&&share!=0 ;)
{
num = share * (UDElementType)divisor.Elements[divisorIdx];
if(dividend.GtEqualBase(subDividendIdx,num))
{
if(num!=0) dividend.SubstractBase(subDividendIdx,num);
--subDividendIdx;
--divisorIdx;
}
else
{
--share;
ret.Borrow(retIdx);
//ret.Elements[retIdx]=--share;
dividend = rdividend;
if(share==0) break;
subDividendIdx = rdividendIdx;
divisorIdx = rdivisorIdx;
dividend.SubstractBase(dividendIdx+1,share*(UDElementType)divisor.Elements[divisorIdx+1]);
}
}
}
if(sign1!=sign2) ComplementOfTwo(ret);
return ret;
}
|