1

I found two ways of conversion from any base to base 10 . the first one is the normal one we do in colleges like 521(base-15) ---> (5*15^2)+(2*15^1)+(1*15^0)=1125+30+1 = 1156 (base-10) . my problem is that i applied both methods to a number (1023456789ABCDE(Base-15)) but i am getting different result . google code jam accepts the value generated from second method only for this particular number (i.e 1023456789ABCDE(Base-15)) . for all other cases both generates same results . whats big deal with this special number ?? can anybody suggest ...

#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;
}
Altaf Hussain
  • 25
  • 1
  • 1
  • 6

3 Answers3

2

Consider using std::stol(ref) to convert a string into a long. It let you choose the base to use, here an example for your number wiuth base 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
}
tgmath
  • 12,813
  • 2
  • 16
  • 24
  • this one is really helpful , i tried your code but have to change long n to unsigned long long and stol to stoull because converted number is very large 10^18 . any ways thanks a lot. – Altaf Hussain Aug 21 '14 at 06:54
1

pow(base, i) uses floating point and so you loose some precision on some numbers.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • 1
    Right. `double` is generally only good for no more than 16 digits, see http://en.wikipedia.org/wiki/Double-precision_floating-point_format – Mark Ransom Aug 20 '14 at 16:19
1

Exceeded double precision.

Precision of double, the return value from pow(), is precise for at least DBL_DIG significant decimal digits. DBL_DIG is at least 10 and typically is 15 IEEE 754 double-precision binary.

The desired number 29480883458974409 is 17 digits, so some calculation error should be expected.

In particular, sum += pow(base,i)*value[14-i] is done as a long long = long long + (double * long long) which results in long long = double. The nearest double to 29480883458974409 is 29480883458974408. So it is not an imprecise value from pow() that causes the issue here, but an imprecise sum from the addition.

@Mooing Duck in a comment references code to avoid using pow() and its double limitation`. Following is a slight variant.

unsigned long long ullongpow(unsigned value, unsigned exp) {
  unsigned long long result = !!value;
  while (exp-- > 0) {
    result *= value;
  }
  return result;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256