Преобразуйте плавание в строку

Как я могу преобразовать целое число с плавающей точкой в строку в C/C++ без библиотечной функции sprintf?

Я ищу функцию, например. char *ftoa(float num) это преобразовывает num к строке и возвратам это.

ftoa(3.1415) должен возвратиться "3.1415".

18
задан MD XF 11 October 2017 в 02:47
поделиться

4 ответа

Когда вы имеете дело с числами fp, это может стать очень сложным, но алгоритм упрощен и похож на ответ Эдгара Холлиса; кудос! Он сложен, потому что когда вы имеете дело с числами с плавающей точкой, вычисления будут немного смещены в зависимости от точности, которую вы выбрали. Вот почему сравнение числа с плавающей точкой с нулем не является хорошей практикой программирования.

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

char fstr[80];
float num = 2.55f;
int m = log10(num);
int digit;
float tolerance = .0001f;

while (num > 0 + precision)
{
    float weight = pow(10.0f, m);
    digit = floor(num / weight);
    num -= (digit*weight);
    *(fstr++)= '0' + digit;
    if (m == 0)
        *(fstr++) = '.';
    m--;
}
*(fstr) = '\0';
11
ответ дан 30 November 2019 в 07:03
поделиться
  1. Используйте log-функцию, чтобы узнать величину m вашего числа. Если величина отрицательная, выведите "0." и соответствующее количество нулей.
  2. Последовательно разделите на 10^m и приведите результат к int, чтобы получить десятичные цифры. m-- для следующей цифры.
  3. Если вы столкнулись с m==0, не забудьте вывести десятичную точку ".".".
  4. Прервитесь после пары цифр. Если m>0 при разрыве, не забудьте напечатать "E" и itoa(m).

Вместо log-функции вы также можете напрямую извлечь экспоненту путем сдвига битов и коррекции смещения экспоненты (см. IEEE 754). В Java есть функция double-to-bits для получения двоичного представления.

6
ответ дан 30 November 2019 в 07:03
поделиться

Можно попробовать , если «varname» в локальных () (вероятно, также необходимо проверить globals () и, возможно, некоторые другие места), или просто прочитать из переменной и поймать исключение NameError , которое будет выдано, когда оно не существует.

Но если вы просто хотите, чтобы else-case , если __ name __ = = '__ main __' , почему бы просто не сделать:

if __name__ == '__main__'
    myvar = 'as_main'
else:
    myvar = 'as_import'
-121--4605225-

Ошибка при доступе к переменной перед ее инициализацией. Значение неинициализированной переменной не равно None; доступ к нему просто вызывает исключение.

Исключение можно перехватить, если вам нравится:

>>> try:
...    foo = x
... except NameError:
...    x = 5
...    foo = 1

В классе можно задать значение по умолчанию None и проверить, не изменилось ли оно в конкретном экземпляре (при условии, что None не является допустимым значением для данной переменной):

class Foo(object):
    bar = None
    def foo(self):
        if self.bar is None:
            self.bar = 5
        return self.bar
-121--4605224-

Имеются две основные проблемы:

  1. Преобразование битового представления в последовательность символов
  2. Выделение достаточного объема памяти для хранения символов.

Самый простой способ решения второй части - выделить достаточно большой блок для каждого возможного ответа. Начни с этого. Позже вы захотите быть умнее, но не беспокойтесь, пока не решите числовую часть проблемы.

Имеются два набора инструментов для решения цифровой части задачи: прямое битовое манипулирование (маскирование, сдвиг и т.д.) и арифметическая операция (*, + ,/, плюс, возможно, связь математических функций регистрация () ).

В принципе, вы могли бы обращаться к побитовому представлению напрямую, но это не было бы портативным в случае, если плавающие форматы представления точки изменятся в будущем. Метод , предложенный edgar.holleis , должен быть портативным.

1
ответ дан 30 November 2019 в 07:03
поделиться
 /*
  * Program to convert float number to string without using sprintf
  */

#include "iostream"    
#include "string"    
#include "math.h"

# define PRECISION 5

using namespace std;

char*  floatToString(float num)
{
   int whole_part = num;
   int digit = 0, reminder =0;
   int log_value = log10(num), index = log_value;
   long wt =0;

   // String containg result
   char* str = new char[20];

   //Initilise stirng to zero
   memset(str, 0 ,20);

   //Extract the whole part from float num
   for(int  i = 1 ; i < log_value + 2 ; i++)
   {
       wt  =  pow(10.0,i);
       reminder = whole_part  %  wt;
       digit = (reminder - digit) / (wt/10);

       //Store digit in string
       str[index--] = digit + 48;              // ASCII value of digit  = digit + 48
       if (index == -1)
          break;    
   }

    index = log_value + 1;
    str[index] = '.';

   float fraction_part  = num - whole_part;
   float tmp1 = fraction_part,  tmp =0;

   //Extract the fraction part from  num
   for( int i= 1; i < PRECISION; i++)
   {
      wt =10; 
      tmp  = tmp1 * wt;
      digit = tmp;

      //Store digit in string
      str[++index] = digit +48;           // ASCII value of digit  = digit + 48
      tmp1 = tmp - digit;
   }    

   return str;
}


//Main program
void main()
{
    int i;
    float f = 123456.789;
    char* str =  floatToString(f);
    cout  << endl <<  str;
    cin >> i;
    delete [] str;
}
3
ответ дан 30 November 2019 в 07:03
поделиться