alexander remus
alexander remus

Reputation: 429

Number changing value when assigned to variable?

I have a little problem when assigning a result to a variable, this is happening the first time to me now. I call Convert() with "aaa" as a parameter, here is my output:

aaa

**676** *(value  from cout)* = 26^(3-1)*1        **675** *(value of the variable)*

+26 = 26^(3-2)*1 700

+1 = 26^(3-3)*1  701

701

And here the code:

string alphabet="abcdefghijklmnopqrstuvwxyz";

unsigned long long Convert(string &str){
  unsigned long long wvalue=0;
  for(int i=0;i<str.size();++i){
    size_t found=alphabet.find(str[i]);
    if(found==string::npos)
      cout<<"Please enter only lowercase letters of the english alphabet!"<<endl;

    unsigned long long add=((found+1)*pow(26,(str.size()-(i+1))));
    wvalue+=add;
    if(i>0)cout<<"+";
    cout<<"\t"<<((found+1)*pow(26,(str.size()-(i+1))))<<" = "<<"26^("<<str.size()<<"-"<<(i+1)  <<")*"<<(found+1)<<"\t"<<wvalue<<endl;
  }
  return wvalue;
}

Chances are I'm missing something awfully obvious, but I cannot figure it out.

((found+1)*pow(26,(str.size()-(i+1)))) 

is doing the calculation, and it is doing as it is supposed to, the result within the cout-statment is correct. But the variable is substracted by 1 in the first two assignments.

Upvotes: 0

Views: 173

Answers (1)

leemes
leemes

Reputation: 45745

pow is a floating-point function. It takes and returns floating point numbers. Assigning a floating-point number to an integer variable truncates it to an integer number, so it might have been 675.9999999 just before the assignment, which will turn into 675 when assigned to the integer variable add.

cout also rounds floating-point numbers, depending on the configuration for example to 6 significant digits. 676.0 is a better approximation than 675.999, so you see 676 in the output.

Since you don't want to calculate with real numbers but only with integral numbers, you better stay with integral functions. To take 26 to the power of n, better use multiplication n times. Since you already use a loop, and like to have the next power of 26 for every character, the best is to add a variable in which you keep the current power value, like this:

unsigned long long currentFactor = 1;
for (...) {
    ...
    unsigned long long add = currentFactor * (found+1);
    wvalue += add;
    currentFactor *= 26;
}

Also note that you don't have to find the character in an alphabet string. You can also just use character arithmetic to do this:

int charNumber(char c) {
    if (c >= 'a' && c <= 'z')
        return c - 'a';   // calculate the position of c relative to 'a'
    else
        return -1;        // error
}

Upvotes: 2

Related Questions