0

Is it possible to take a decimal number as input from the user without using float/double data type?

And this number has to be used further for calculation.

I'm making a function to calculate the square root of a number without using cmath library, I'm doing this for a DSP that doesn't have FPU so I can't use float/double.

If I will be using string to take input as decimal number from the user then how can I convert it into a number, and if it is converted into a number then what should be the return type of the square root function (the root will be a fractional number)?

If possible please suggest some alternative way instead of stings.

I know it is related to fixed point arithmetic but I don't know how to implement it in c++.

  • Do you need decimal output? – NathanOliver Apr 28 '20 at 15:04
  • Provide information about hardware, maybe this hardware is shipped with library (specific for it) which already has such functionality or something similar. – Marek R Apr 28 '20 at 15:10
  • @NathanOliver Yes, I need decimal output. Example- square root of 5 is 2.2360679775 – shubham1355 Apr 28 '20 at 15:13
  • @MarekR I haven't decided the hardware yet. I just need to implement a self-made square root function in any 32/64 bit DSP that has no FPU. – shubham1355 Apr 28 '20 at 15:16
  • Actually, you *can* use floating point variables; you'll need floating point software support. Many early processors did not have support for floating point, so compiler manufacturers supplied floating point libraries. They may not be as fast as an FPU, but it's there. – Thomas Matthews Apr 28 '20 at 15:22
  • 1
    Search the internet for "fixed point notation". – Thomas Matthews Apr 28 '20 at 15:23
  • I don't understand how a DSP with no float calculation capability will be able to compile and run a C++ programme. We need more context to be able to help you – Damien Apr 28 '20 at 15:25
  • You should search the internet for C++ libraries for the DSP you are using. Unless you have a weird or unique DSP, there should be some libraries. Often, the DSP manufacturer or distributor will have examples and software development kits (SDK) for you to use. – Thomas Matthews Apr 28 '20 at 15:27
  • I recommend you use floating point variables for input and output. Switch over to Fixed Point for your calculations. – Thomas Matthews Apr 28 '20 at 15:29
  • @ThomasMatthews Actually I am trying to make a math library of my own and the problem is I am not allowed to use any of the available libraries or software for floating point to fixed point conversion. – shubham1355 Apr 28 '20 at 15:33
  • @shubham1355: See https://stackoverflow.com/questions/4657468/fast-fixed-point-pow-log-exp-and-sqrt/4657849#4657849 for a fixed-point `sqrt` and some other math functions. That answer doesn't cover I/O, so if that's all you still need then please update the question and I'll give it a shot. – MSalters Apr 28 '20 at 16:10
  • @MSalters Thanks for the link but I do have my own algorithm for these functions (but it uses double and floats). Actually I have already written code but now I just need a way to replace doubles and floats with some other data type (since my DSP doesn't have FPU support). – shubham1355 Apr 28 '20 at 16:45

2 Answers2

1

Foreword: Compilers can implement software floating point operations for CPU's which do not have floating point hardware, so it is often not a problem to use float and double on such systems.

I recommend using the standard fundamental floating point types as long as they are supported by your compiler.

Is it possible to take a decimal number as input from the user without using float/double data type?

Yes. User input is done using character streams. You can read input into a string without involving any numeric type.

And this number has to be used further for calculation.

To do calculation, you must first decide how you would like represent the number. There are several alternatives to hardware floating point:

  • Fixed point: Use the integer 100 to represent 0.0100 for example.
  • Software floating point: Use one integer to represent mantissa, another integer to represent the exponent and a boolean to represent sign.
  • Rational numbers: Use one integer to represent nominator and another to represent denominator.
  • Probably many others...

Each of these have different implemenations for different arithmetic operations.

Fixed point is the simplest and probably most efficient, but has both small range and poor precision near zero (well, equal precision across the entire range but poor compared to floating point which has high precision near zero and very poor precision far from zero).

Software floating point allows potentially reproducing hardware behaviour by following the ubiquitous IEEE-754 standard.

Rational numbers have problems with overflowing as well as redundant representations. I don't think they are used much except with arbitrary precision integers.

(the root will be a fractional number)

Technically, most roots are irrational and thus not fractional. But since irrational numbers are not representable by computers (except in symbolic form), the best we can achieve is some fractional number close to the actual root.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

Here's my solution.

In summary, 12345 has

5 1's units, 4 10's units, 3 100's units, 2 1000's units and 1 10,000's units.

What's below is verbose description of doing this in C++. It doesn't detect every possible error like the user typing MAXINT+1 and the output returning -MAXINT; fgets has some issues regarding buffer overflows but you probably take input from some source within the greater program anyhow but just to show the principal.

int error=0;            //error condition if you can't 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[column];
   //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
   }
}

EDIT: I realise I didn't read the full question and there's also a need for a square root function. When FPU's were added extras in 8-bit, 8086, 286 and 386SX days, the standard technique was to store a look up table in memory. There are mathematical functions you can use involving natural logarithms but the expense involved in processor time was such that it was cheaper just to make a table with each value that you wanted to sqrt and lookup the table for the value.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Stephen Duffy
  • 467
  • 2
  • 14