Я нашел два способа преобразования из любой базы в базу 10. первый нормальный, который мы делаем в колледжах, таких как 521 (base-15) —> (5 * 15 ^ 2) + (2 * 15 ^ 1) + (1 * 15 ^ 0) = 1125 + 30 + 1 = 1156 (основание-10). моя проблема в том, что я применил оба метода к числу (1023456789ABCDE (Base-15)), но я получаю разные результаты. google code jam принимает значение, сгенерированное вторым методом, только для этого конкретного номера (т. е. 1023456789ABCDE (Base-15)). для всех остальных случаев оба дают одинаковые результаты. что за дела с этим специальным номером ?? Кто-нибудь может предложить …
#include <iostream>
#include <math.h>
using namespace std;
int main()
{ //number in base 15 is 1023456789ABCDE
int value[15]={1,0,2,3,4,5,6,7,8,9,10,11,12,13,14};
int base =15;
unsigned long long sum=0;
for (int i=0;i<15;i++)
{
sum+=(pow(base,i)*value[14-i]);
}
cout << sum << endl;
//this prints 29480883458974408
sum=0;
for (int i=0;i<15;i++)
{
sum=(sum*base)+value[i];
}
cout << sum << endl;
//this prints 29480883458974409
return 0;
}
Рассмотреть возможность использования std::stol
(ссылка) чтобы преобразовать строку в длинный.
Это позволяет вам выбрать базу для использования, вот пример для вашего номера с базой 15
,
int main()
{
std::string s = "1023456789ABCDE";
long n = std::stol(s,0,15);
std::cout<< s<<" in base 15: "<<n<<std::endl;
// -> 1023456789ABCDE in base 15: 29480883458974409
}
pow(base, i)
использует с плавающей точкой, и поэтому вы теряете некоторую точность на некоторых числах.
Превышен double
точность.
Точность double
, возвращаемое значение от pow()
, точно по крайней мере DBL_DIG
значащие десятичные цифры. DBL_DIG
я сидела наименее 10 и обычно 15 Бинарный двоичный код IEEE 754.
Желаемый номер 29480883458974409
17 цифр, поэтому следует ожидать некоторой ошибки в расчетах.
Особенно, sum += pow(base,i)*value[14-i]
сделано как long long = long long + (double * long long)
что приводит к long long = double
, Ближайший double
в 29480883458974409
является 29480883458974408
, Так что это не неточное значение от pow()
это вызывает проблему здесь, но неточная сумма от сложения.
@Mooing Duck в комментариях ссылается на код, чтобы избежать использования pow()
И его double
limitation`. Ниже приведен небольшой вариант.
unsigned long long ullongpow(unsigned value, unsigned exp) {
unsigned long long result = !!value;
while (exp-- > 0) {
result *= value;
}
return result;
}