だいすうえんざん
だいすうえんざん
変数にはデータ型があり、各データ型には独自の範囲があることが知られています.データがこのタイプの範囲を超えると、エラーが発生します.この現象を「オーバーフロー」と呼びます.もちろん、各変数のアドレスに格納されているデータは、データ型が示す範囲を超えてはならない.×××intの表示範囲は-128~127であり、データ型の表示範囲が最も大きいのはlong long型であり、表示範囲は:0 x 7 FFFFFFFFFFFFFFFFF~0 x 8000000000000000000である.Long long型のデータ型もより大きなデータを表すことができませんが、もし私たちがいくつかの大きなデータを操作したいなら、このような問題をどのように解決すればいいのでしょうか.
ビッグデータを解決する方法は一般的に1つの文字列で表され、操作時にも文字列が用いられる.次に、文字列を使用してビッグデータ間の加算、減算、乗算、除算の演算について主に説明します.
◆加算
加算操作には主に次のようなケースがあります.2つのデータがオーバーフローしていない場合、その結果もオーバーフローしていない場合、直接「+」操作を行うことができます.2つのデータがオーバーフローしていない場合、2つのデータが異号である場合、加算後もオーバーフローしない場合は「+」を直接行い、残りの場合は文字列で保存し、最後のビットから加算します.期間には、キャリーを保存する変数を設定します.
◆減算
減算操作は、一般的に、2つのデータが同じ番号でオーバーフローしていない場合、または2つのデータがオーバーフローしていない場合、結果的にオーバーフローしていない場合、直接「-」にすることができます.2つのデータのうち少なくとも1つがオーバーフローし、2つのデータが異なる場合、「+」を呼び出して「-」の操作を実現することができます.2つのデータが同じ番号である場合、「-」操作を再定義する必要があります.これを演算します.
◆乗算
2つのデータのうち1つが0の場合、その結果も0になります.両方のデータがオーバーフローせず、結果もオーバーフローしない場合は、直接「*」を行うことができます.そうしないと、前と同じように「*」を再定義します.
◆除算
2つのデータを除算するには、除数が0でないことを保証しなければならない.被除数<除数であれば、その結果は0であり、除数が+/-1であれば、結果の絶対値と被除数の絶対値は等しく、記号は除数と被除数の記号に関係し、2つのデータの絶対値が等しいと、結果は+/-1である.両方のデータがオーバーフローしていない場合は「/」を直接行い、そうでない場合は「/」を再定義します.
以下は具体的なプログラムコードです:(詳細なコメント付き)
変数にはデータ型があり、各データ型には独自の範囲があることが知られています.データがこのタイプの範囲を超えると、エラーが発生します.この現象を「オーバーフロー」と呼びます.もちろん、各変数のアドレスに格納されているデータは、データ型が示す範囲を超えてはならない.×××intの表示範囲は-128~127であり、データ型の表示範囲が最も大きいのはlong long型であり、表示範囲は:0 x 7 FFFFFFFFFFFFFFFFF~0 x 8000000000000000000である.Long long型のデータ型もより大きなデータを表すことができませんが、もし私たちがいくつかの大きなデータを操作したいなら、このような問題をどのように解決すればいいのでしょうか.
ビッグデータを解決する方法は一般的に1つの文字列で表され、操作時にも文字列が用いられる.次に、文字列を使用してビッグデータ間の加算、減算、乗算、除算の演算について主に説明します.
◆加算
加算操作には主に次のようなケースがあります.2つのデータがオーバーフローしていない場合、その結果もオーバーフローしていない場合、直接「+」操作を行うことができます.2つのデータがオーバーフローしていない場合、2つのデータが異号である場合、加算後もオーバーフローしない場合は「+」を直接行い、残りの場合は文字列で保存し、最後のビットから加算します.期間には、キャリーを保存する変数を設定します.
◆減算
減算操作は、一般的に、2つのデータが同じ番号でオーバーフローしていない場合、または2つのデータがオーバーフローしていない場合、結果的にオーバーフローしていない場合、直接「-」にすることができます.2つのデータのうち少なくとも1つがオーバーフローし、2つのデータが異なる場合、「+」を呼び出して「-」の操作を実現することができます.2つのデータが同じ番号である場合、「-」操作を再定義する必要があります.これを演算します.
◆乗算
2つのデータのうち1つが0の場合、その結果も0になります.両方のデータがオーバーフローせず、結果もオーバーフローしない場合は、直接「*」を行うことができます.そうしないと、前と同じように「*」を再定義します.
◆除算
2つのデータを除算するには、除数が0でないことを保証しなければならない.被除数<除数であれば、その結果は0であり、除数が+/-1であれば、結果の絶対値と被除数の絶対値は等しく、記号は除数と被除数の記号に関係し、2つのデータの絶対値が等しいと、結果は+/-1である.両方のデータがオーバーフローしていない場合は「/」を直接行い、そうでない場合は「/」を再定義します.
以下は具体的なプログラムコードです:(詳細なコメント付き)
#pragma once
#include
using namespace std;
//
#include
#include
#define UN_INT 0xcccccccccccccccc
#define MAX_INT64 0x7FFFFFFFFFFFFFFF
#define MIN_INT64 0x8000000000000000
typedef long long INT64;
class BigData
{
public:
BigData::BigData(INT64 value = 0xcccccccccccccccc) //
:_value(value)
{
INT64ToString();
}
BigData(const char *ptr) //
{
if (NULL == ptr) //
{
return;
}
char *src = (char *)ptr;
char cSymbol = ptr[0]; //
if (cSymbol == '+' || cSymbol == '-') // +/-
{
src++;
}
else if (cSymbol >= '0' && cSymbol <= '9') // +/-, 12345,
{
cSymbol = '+';
}
else
{
return;
}
while ('0' == *src) // 000001234567
{
src++;
}
_strData.resize(strlen(ptr) + 1); //_strData , string resize
_strData[0] = cSymbol; // +/- (cSymbol ‘+’)
_value = 0; //
int count = 1;
while (*src >= '0' && *src <= '9') //
{
_value = _value * 10 + (*src - '0');
_strData[count++] = *src;
src++;
}
_strData.resize(count);
if (cSymbol == '-') // '-'
{
_value = (-1) * _value;
}
}
//
BigData operator+(const BigData& bigData) //+ ( , this)
{
if (IsINT64Overflow() && bigData.IsINT64Overflow())
{
if (_strData[0] != bigData._strData[0]) // ,
{
return BigData(_value + bigData._value); //
}
// , ,
//10 - (2) = 8 10( ) 7( )
//(-10) - (-2) = -8 -13( ) -7( )
else if ((_value >= 0 && MAX_INT64 - _value >= bigData._value) ||
(_value 0 && MIN_INT64 + _value <= bigData._value) ||
(_value = bigData._value))
{
return BigData(_value - bigData._value);
}
}
}
else
{
if (_strData[0] != bigData._strData[0]) //
{
return BigData(Add(_strData, bigData._strData).c_str());
}
else
{
return BigData(Sub(_strData, bigData._strData).c_str());
}
}
}
BigData operator*(const BigData& bigData) // *
{
if (_value == 0 || bigData._value == 0)
{
return BigData(INT64(0)); // long long 0
}
if (IsINT64Overflow() && bigData.IsINT64Overflow()) //
{
//10 / 2 = 5 6( ) 3( )
//10 / (-2) = -5 -6( ) -2( )
if (_strData[0] == bigData._strData[0])
{
if ((_value > 0 && MAX_INT64 / _value >= bigData._value) ||
(_value 0 && MAX_INT64 / _value >= -bigData._value) ||
(_value Rsize) // ,
{
swap(left, right);
swap(Lsize, Rsize);
}
string ret;
ret.assign(Lsize + Rsize - 1, '0'); //assign Lsize+Rsize-1 , ‘0’
int len = ret.size();
int num = 0;
ret[0] = cSymbol;
for (int i = 1; i 0)
{
pleft++;
i++;
len--;
}
len++;
}
if (len > right.size())//pLeft pRight 0, pLeft 0
{
pleft++;
len--;
i++;
}
if (len + i > left.size() - 1)
{
break;
}
}
return ret;
}
char loopmove(char* pleft, int Lsize, const char* pright, int Rsize)
{
assert(pleft != NULL && pright != NULL);
char pret = '0';
while (1) // >
{
if (!IsLeftString(pleft, Lsize, pright, Rsize))
{
break;
}
for (int i = 0; i 0)
{
pleft++;
Lsize--;
}
pret++;
}
return pret;
}
bool IsLeftString(const char* pleft, int Lsize, const char* pright, int Rsize) //
{
if (Lsize > Rsize || (Lsize == Rsize && strcmp(pleft, pright) >= 0))
{
return true;
}
return false;
}
friend std::ostream& operator<