Aragok
Aragok

Reputation: 363

How to count the decimal places of an double variable in c++?

for a course at my university i need to write a program which converts a number into natural language e.g. if the user enters "2.55" the program outputs "two point five five". And i'm close to finish it the only thing i cant get are numbers after the point. I'm not allowed to use strings. Here is how i tried to get the count of decimal places:

i=0;
while((wert - (long int)wert) != 0){
    wert /= 10;
    i++;
}

But it gives me the value of 356 decimal places for the example number "2.55". Is there any method wihout using strings to count the decimal places?

Best Regards

Upvotes: 0

Views: 3862

Answers (5)

Zaki Hassan Naqvi
Zaki Hassan Naqvi

Reputation: 7

char* fractpart(double f)
{
char chrstr[5];
char charary={'1','2','3',....,'0'};
int intary={1,2,3,...,0};
int count=0,x,y;
f=f-(int)f;
        while(f<=1)
        {
         f=f*10;
           for(y=0;y<10;y++)
           {
               if((int)f==intary[y])
               { 
               chrstr[count]=charary[y];
               break;
               }
           }
   f=f-(int)f;
      if(f<=0.01 || count==4)
      break;
      if(f<0)
      f=-f;
      count++;
}
     return(chrstr);
}

Upvotes: 1

Patricia Shanahan
Patricia Shanahan

Reputation: 26185

The IEEE 64-bit binary number closest to 2.55 is 2.54999999999999982236431605997495353221893310546875, which only has 50 digits after the decimal point.

The repeated division makes no sense. Ignoring rounding error, the values of wert would be 2.55, 0.255, 0.0255, 0.00255, etc. none of which is equal to any long. The loop terminates when wert underflows to zero.

Instead, you should be multiplying by 10. However, if you keep the leading digits you may get a number too large to store as a long before getting equality. Instead, I suggest subtracting off the integer part at each step, and stopping when the result is zero.

That will still lead to a 50 decimal place answer, but if your professor insists on double, maybe that is what is wanted.

Upvotes: 1

user207421
user207421

Reputation: 311050

If the user is entering the number, it will be coming in as a string, or shall we say into a byte array, so there is no need to bring floating-point into it at all. Just locate the decimal place in the data and then start counting digits.

NB The question in your title is meaningless. Floating-point variables don't have decimal places, they have binary places, and decimal and binary places are incommensurable. If your professor wants you to use floating-point he needs re-education himself.

Upvotes: 2

Axel
Axel

Reputation: 14169

You have to know the maximal number of digits you have to support after the point.Let's say n digits maximum. Multiply the fractional part of your number by 10^n and then shift the resulting number right until the last digit is different from 0 to remove trailing zeroes. Then print the digits one by one:

void printDigitsAfterPoint(double x) {
    int k = Math.round((x-(int) x)*Math.pow10(n));
    // remove trailing zeroes
    while (k!=0 && k%10==0) {
        k/=10;
    }
    // output digits
    while (k!=0) {
        output(k%10); // you already should have a method like this...
        k/=10;
    }
}

Make sure to add code for handling negative values of x. I'm sure your prof will try that...

EDIT: Forgot to change the declaration. Fixed.

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234875

You will not be able to use a double to do this due to floating point precision. For example, a double set to 0.2 will have many more decimal places than 1 since 0.2 cannot be represented precisely. (Why not examine the actual value of the double in your debugger?) 2.55 cannot be represented precisely either.

Probably the simplest thing for you to do here is use a string to represent your number and base your parser on that.

Upvotes: 2

Related Questions