views:

1557

answers:

6

Today I appeared for an interview, and the question was writing my own "char * ftoa(float num) " in C, C++ and Java.

Yes, I know float numbers follow IEEE standard while allocating their memory, but I don't know float to char conversion by using Mantissa and Exponent in C.

I don't have any idea to solve the above problem in C++ and JAVA.

I/P to the ftoa(): 1.23

O/P from the ftoa(): 1.23 (char format).

Thanks in advance ...

+4  A: 
  1. Use the log-function to find out the magnitude m of your number. If the magnitude is negative print "0." and an appropriate amount of zeros.
  2. Consecutively divide by 10^m and cast the result to int to get the decimal digits. m-- for the next digit.
  3. If you came accross m==0, don't forget to print the decimal point ".".
  4. Break off after a couple of digits. If m>0 when you break of, don't forget to print "E" and itoa(m).

Instead of the log-function you can also directly extract the exponent by bitshifting and correcting for the exponent's offset (see IEEE 754). Java has a double-to-bits function to get at the binary representation.

edgar.holleis
A: 

Well, you will have to calculate each digit for your own. That means a lot of dividing, multiplying, and rounding. You also need an intended precision, either as parameter or as a sensible default.

Svante
A: 

You have two major problems:

  1. Converting the bit representation into a string of characters
  2. Allocating enough memory to store the characters.

The simplest way to solve the second part is to allocate a big enough chunk for every possible answer. Start with that. Later you'll want to be more clever, but don't bother until you've solved the numeric part of the problem.

You have two sets of tools available for dealing with the numeric part of the problem: direct bit manipulation (masking, shifting, etc) and arithmetic operation (*,+,/, plus possibly math functions link log()).

In principle you could tackle the bitwise representation directly, but that would not be portable in the event that floating point representation formats change in the future. The method suggested by edgar.holleis should be portable.

dmckee
A: 

Here http://www.edaboard.com/ftopic41714.html You have implementation of ftoa. BTW: Strange question for interview :| Writing such function might not be obvious even for someone profession programmers.

Tomek Tarczynski
+1  A: 

When you're dealing with fp numbers, it can get very compex but the algorithm is simplistic and similar to edgar holleis's answer; kudos! Its complex because when you're dealing with floating point numbers, the calculations will be a little off depending on the precision you've chosen. That's why its not good programming practice to compare a float to a zero.

But there is an answer and this is my attempt at implementing it. Here I've used a tolerance value so you don't end up calculating too many decimal places resulting in an infinite loop. I'm sure there might be better solutions out there but this should help give you a good understanding of how to do it.

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';
Sophy Pal
@Pal, Good answer. thanks
SIVA
A: 
 /*
  * 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;
}
Rahul Naik