Можно ли принять десятичное число в качестве ввода от пользователя без использования типа данных float / double? - PullRequest
0 голосов
/ 28 апреля 2020

Можно ли принять десятичное число в качестве ввода от пользователя без использования типа данных с плавающей запятой / double?

И это число необходимо использовать для дальнейшего расчета.

Я делая функцию для вычисления квадрата root числа без использования библиотеки cmath, я делаю это для DSP, у которого нет FPU , поэтому я не могу использовать float / double .

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

Если возможно, предложите какой-нибудь альтернативный способ вместо укусов.

Я знаю, что это связано с фиксированной точкой арифметика c но я не знаю, как реализовать это в с ++.

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Предисловие: Компиляторы могут реализовывать программные операции с плавающей запятой для процессоров, у которых нет аппаратного обеспечения с плавающей запятой, поэтому часто использование float и double в таких системах не является проблемой.

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

Можно ли получить десятичное число в качестве ввода от пользователя без использования типа данных с плавающей запятой / double?

Да. Ввод пользователя осуществляется с использованием символьных потоков. Вы можете читать входные данные в строку, не используя какой-либо тип чисел c.

И это число необходимо использовать для расчетов в дальнейшем.

Для выполнения вычислений вы сначала нужно решить, как бы вы хотели представить число. Существует несколько альтернатив аппаратной плавающей точке:

  • Фиксированная точка: используйте целое число 100, например, для представления 0,0100.
  • Программная плавающая точка: используйте одно целое число для представления мантиссы, другое целое число для представления показателя степени и логического значения для представления знака.
  • Рациональные числа: используйте одно целое число для представления знаменателя, а другое - для представления знаменателя.
  • Возможно, многие другие ...

Каждый из них имеет разные реализации для различных арифметических c операций.

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

Программная плавающая точка позволяет потенциально воспроизводить поведение оборудования, следуя вездесущему стандарту IEEE-754.

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

(root будет дробным числом)

Технически, большинство корней иррационально и, таким образом, не дробный. Но поскольку иррациональные числа не могут быть представлены компьютерами (кроме как в символьной форме c), лучшее, что мы можем достичь, это некоторое дробное число, близкое к фактическому root.

0 голосов
/ 28 апреля 2020

Вот мое решение.

В итоге, 12345 имеет 5 единиц 1, 4 единицы 10, единицы 3 100, 2 единицы 1000 и 1 10000 единиц.

То, что ниже, является многословным Описание этого в C ++. Он не обнаруживает каждую возможную ошибку, например, когда пользователь вводит MAXINT + 1, а вывод возвращает -MAXINT; У fgets есть некоторые проблемы, связанные с переполнением буфера, но вы, во всяком случае, берете ввод из какого-то источника в большей программе, но только для того, чтобы показать принципал.

int error=0;            //error condition if you cant indicate err by -1 or such
int output=0;         
char input[256];
fgets(input,255,stdin); //get input

//arrange the input for our purpose
input=trim(input);      //trim whitespace
input=strrev(input);    //reverse it (12345 now equals 54321)

//set up a loop
int len=strlen(input);  //length of output
int column=0;           //iterates through each char in input
int units=1;            //we start with the 1's column and then 10s, 100's, etc
while (column<len){
   int val=input[coloumn];
   //nitty gritty
   if ((val>'0')&&(val<'9')){  //note the quotes amounting to int values 48 and 57
      val-=48;          //convert the ascii/utf-8 digit into its intval
      val*=units;       //multiply it by the units of the column 1s,10s,100s,etc
      output+=val;      //add it to the output
      units*=10;        //end of this iteration, set up for next unit scale
   }
   else if (val=='-'){  //test for the unique circumstance of the minus sign
      output*=-1;
      break;
   }
   else if (val=='+'){  //test if the user is a tit and puts the positive sign
      break;
   }
   else{
      error=1;          //the user typed a character not conforming to an intval
   }
}

РЕДАКТИРОВАТЬ: я понимаю, что не прочитал полный вопрос, и есть также потребность в квадратной root функции. Когда в 8-битные, 8086, 286 и 386SX дни были добавлены дополнительные модули, стандартным методом было сохранение таблицы поиска в памяти. Существуют математические функции, которые вы можете использовать, включая натуральные логарифмы, но затраты на процессорное время были таковы, что дешевле было просто создать таблицу с каждым значением, которое вы хотите получить, и поискать таблицу по значению.

...