C / C ++ считая количество десятичных знаков?

Допустим, что ввод от пользователя является десятичным числом, напр. 5.2155 (имеющий 4 десятичных знака). Может храниться свободно (int, double) и т. Д.

Есть лиclever (или очень простой) способ узнать, сколько десятичных чисел имеет число? (вроде как вопрос, как вы обнаружите, что число является четным или нечетным, маскируя последний бит).

Ответы на вопрос(11)

Вот полная программа

 #include <iostream.h>
 #include <conio.h>
 #include <string.h>
 #include <math.h>

     char charary[10]={'1','2','3','4','5','6','7','8','9','0'};
     int intary[10]={1,2,3,4,5,6,7,8,9,0};

     char* intpart(double);
     char* fractpart(double);

      int main()
      {
      clrscr();
      int count = 0;
      double d = 0;
      char intstr[10], fractstr[10];
     cout<<"Enter a number";
     cin>>d;
     strcpy(intstr,intpart(d));
     strcpy(fractstr,fractpart(d));
     cout<<intstr<<'.'<<fractstr;
     getche();
    return(0);
   }

    char* intpart(double f)
    {
       char retstr[10];
       int x,y,z,count1=0;
       x=(int)f;
            while(x>=1)
            {
               z=x%10;
               for(y=0;y<10;y++)
                {
                 if(z==intary[y])
                 {
                 chrstr[count1]=charary[y];
                 break;
                 }
              }
             x=x/10;
            count1++;
            }
           for(x=0,y=strlen(chrstr)-1;y>=0;y--,x++)
            retstr[x]=chrstr[y];
            retstr[x]='\0';
            return(retstr);
     }

       char* fractpart(double f)
      {
      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); 
 }
char* fractpart(double f)
 {
    int intary={1,2,3,4,5,6,7,8,9,0};
    char charary={'1','2','3','4','5','6','7','8','9','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);
    }

Спустя годы после боя, но я сделал свое собственное решение в трех линиях:

string number = "543.014";    
size_t dotFound;
stoi(number, &dotFound));
string(number).substr(dotFound).size()

Конечно, вы должны проверить прежде, если это действительно поплавок (Сstof(number) == stoi(number) например)

используя формат научной нотации (чтобы избежать ошибок округления):

#include <stdio.h>
#include <string.h>

/* Counting the number of decimals
 *
 * 1. Use Scientific Notation format
 * 2. Convert it to a string
 * 3. Tokenize it on the exp sign, discard the base part
 * 4. convert the second token back to number
*/

int main(){

   int counts;
   char *sign;
   char str[15];
   char *base;
   char *exp10;
   float real = 0.00001;

   sprintf (str, "%E",  real);
   sign= ( strpbrk ( str, "+"))? "+" : "-";

   base = strtok (str, sign);
   exp10 = strtok (NULL, sign);

   counts=atoi(exp10);

   printf("[%d]\n", counts);

   return 0;
}

[5]

Решение Вопроса

Два способа, которые я знаю, но не очень умный, к сожалению, но это скорее ограничение окружающей среды, чем меня :-)

Во-первых, этоsprintf число в большой буфер с"%.50f" отформатируйте строку, удалите завершающие нули, затем посчитайте символы после десятичной точки. Это будет ограниченоprintf Сама семья. Или вы можете использовать строку в качестве ввода пользователем (а неsprintfзначение с плавающей запятой), чтобы вообще избежать проблем с плавающей запятой.

Второе - вычесть целую часть, затем итеративно умножить на 10 и снова вычесть целую часть, пока вы не получите ноль. Это ограничено пределами компьютерного представления чисел с плавающей запятой - на каждом этапе вы можете столкнуться с проблемой числа, которое не может быть точно представлено (так что .2155 на самом деле может быть .215499999998). Что-то вроде следующего (непроверенное, за исключением моей головы, что примерно на одном уровне с COMX-35):

count = 0
num = abs(num)
num = num - int(num)
while num != 0:
    num = num * 10
    count = count + 1
    num = num - int(num)

Если вам известен тип чисел, которые вы получите (например, все они будут от 0 до 4 цифр после десятичной запятой), вы можете использовать стандартные "трюки" с плавающей точкой. сделать это правильно. Например, вместо:

while num != 0:

использование

while abs(num) >= 0.0000001:

Один из способов - прочитать число в виде строки. Найти длину подстроки после десятичной точки и количество десятичных знаков, введенных человеком. Чтобы преобразовать эту строку в число с плавающей запятой, используя

atof(string.c_str());

На другой ноте; всегда полезно иметь дело с операциями с плавающей запятой, чтобы хранить их в специальном объекте, который имеет конечную точность. Например, вы можете хранить точки с плавающей точкой в специальном типе объекта под названием & quot; Десятичная & quot; где целая часть числа и десятичная часть числа являются целыми числами. Таким образом, вы получаете конечную точность. Недостатком этого является то, что вы должны писать методы для арифметических операций (+, -, *, / и т. Д.), Но вы можете легко переписать операторы в C ++. Я знаю, что это отличается от вашего первоначального вопроса, но всегда лучше хранить ваши десятичные дроби в конечной форме. Таким образом, вы также можете ответить на ваш вопрос о том, сколько десятичных чисел имеет число.

Я бы предложил прочитать значение в виде строки, найти десятичную точку и проанализировать текст до и после него как целые числа. Нет ошибок с плавающей запятой или округления.

Как только число преобразуется из представления пользователя (строка, файл OCR-ed-gif и т. Д.) В число с плавающей запятой, вы не обязательно имеете дело с одним и тем же числом. Таким образом, строгим, не очень полезным ответом является «Нет».

Если (case A) вы можете избежать преобразования числа из строкового представления, проблема становится намного проще, вам нужно только посчитать цифры после десятичной точки и вычесть число конечных нулей.

Если вы не можете сделать это (case B), то вам нужно сделать предположение о максимальном количестве десятичных знаков, преобразовать число обратно в строковое представление и округлить до этого максимального числа, используяметод округления к четному, Например, если пользователь вводит 1.1, которое представляется как 1.09999999999999 (гипотетически), преобразуя его обратно в строковые значения, угадайте, что, & quot; 1.09999999999999 & quot ;. Округляя это число, скажем, до четырех десятичных знаков, вы получите «1.1000». Теперь он вернулся кcase A.

Нечто подобное может сработать:

float i = 5.2154;
std::string s;
std::string t;
std::stringstream out;
out << i;
s = out.str();

t = s.substr(s.find(".")+1);
cout<<"number of decimal places: " << t.length();

Что вы имеете в виду «хранится свободно (int»?). После сохранения в int у него, очевидно, осталось ноль десятичных знаков. Двойник хранится в двоичной форме, так что никакого очевидного или простого отношения к «десятичным числам» тоже нет. Почему бы и нет? Вы сохраняете ввод как строку, достаточно длинную, чтобы сосчитать эти десятичные дроби, прежде чем отправлять ее в конечный пункт назначения числовой переменной?

С верхней части моей головы:

начать с дробной части: .2155

многократно умножьте на 10 и выбросьте целую часть числа, пока не получите ноль. Количество шагов будет количеством десятичных знаков. например:

.2155 * 10 = 2.155
.155 * 10 = 1.55
.55 * 10 = 5.5
.5 * 10 = 5.0

4 шага = 4 десятичных знака

Ваш ответ на вопрос