Это сообщение связано с моего предыдущего поста:усечения при использовании неподписанных долго долго
Weird data corruption in C++ code for unsigned long long
Проблема, поднятая в этой должности будет решена, но теперь я столкнулся другой вопрос, связанный с усечением неподписанных долгое длинный тип данных. Это происходит в функции iPow() для повышения базы до степени экспоненты. Исходный код для iPow() разделяли в моем предыдущем посте, но воспроизводится ниже для удобства:
unsigned long long userinput::iPow(){
while(this->revValue)
{
if (this->revValue & 1ULL)
{
this->result *= this->value;
}
this->revValue >>= 1;
this->value *= this->value;
}
return this->result;
}
В приведенной выше функции, значение, revValue, и результат все без знака долго долго. Исходный код для объявления класса был разделен в предыдущем посте, но воспроизводится ниже для удобства:
class userinput{
public:
userinput(unsigned long long);
~userinput();
unsigned long long reverse();
unsigned long long raise_to_reverse();
private:
userinput();
userinput(const userinput&);
void operator=(const userinput&);
private:
unsigned long long value;
unsigned int numDigits;
unsigned long long revValue;
unsigned long long result;
private:
void calc_numDigits();
unsigned long long iPow();
};
Я воспроизводящий ниже выходного GdB для значений this-> значение, this-> revValue, и этом-> результат для каждой итерации цикла в iPow():
Enter a number between 0 and 99999 (exlusive):
1234
Breakpoint 1, userinput::iPow (this=0x7fffffffde10) at program.cpp:49
49 while(this->revValue)
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64
(gdb) p this->revValue
$1 = 4321
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$2 = 1
(gdb) n
53 this->result *= this->value;
(gdb) n
55 this->revValue >>= 1;
(gdb) p this->result
$3 = 1234
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$4 = 2160
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$5 = 1522756
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$6 = 0
(gdb) n
55 this->revValue >>= 1;
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$7 = 1080
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$8 = 2318785835536
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$9 = 0
(gdb) n
55 this->revValue >>= 1;
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$10 = 540
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$11 = 3022197894083133696
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$12 = 0
(gdb) n
55 this->revValue >>= 1;
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$13 = 270
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$14 = 16658586050838462464
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$15 = 0
(gdb) n
55 this->revValue >>= 1;
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$16 = 135
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$17 = 8477297326610710528
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$18 = 1
(gdb) n
53 this->result *= this->value;
(gdb) n
55 this->revValue >>= 1;
(gdb) p this->result
$19 = 1681011244301025280
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$20 = 67
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$21 = 0
(gdb) n
51 if (this->revValue & 1ULL)
(gdb) p this->revValue & 1ULL
$22 = 1
(gdb) n
53 this->result *= this->value;
(gdb) n
55 this->revValue >>= 1;
(gdb) p this->result
$23 = 0
(gdb) n
56 this->value *= this->value;
(gdb) p this->revValue
$24 = 33
(gdb) n
49 while(this->revValue)
(gdb) p this->value
$25 = 0
(gdb)
Как видно на выходе Gdb, максимальное значение достигается этом-> значение $ 17 = 8477297326610710528, после чего значение усекает к ноль в следующей итерации. Следовательно, значение this-> result также обрезается до нуля из-за логики цикла.
Есть ли тип данных, который я могу использовать для печати всех цифр результата iPow(), учитывая диапазон 0-99999 (эксклюзивный)? Или, если нет допустимого типа данных, какую альтернативу я могу использовать для печати всех цифр результата iPow() в stdout?
Пожалуйста, поделитесь своими мыслями.
ТИА Винод
Я думаю, вы должны использовать 'std :: string' – CinCout
@Garg Ankit Как использовать std :: string для обработки внутри iPow()? Я имею в виду, что вам нужны два целых числа для базы и экспоненты? –
Поскольку ваш результат не находится в диапазоне наибольшего типа данных, возможного в 'C++', вам нужно каждый раз сохранять результат в строке.Подобно 'BigInteger' в' Java' – CinCout