Making float to string function

Hello everyone.
I have this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	void reverse(char *in, int isize)
	{
		char t = 0;
		for( int a = 0; a < isize / 2; a++ )
		{
			t = in[a];
			in[a] = in[(isize - 1) - a];
			in[(isize - 1) - a] = t;
		}
	}

	int to_num( char *line, int num )
	{
		int i = 0, base = 10;
		bool isNegative = false;

		if (num == 0)
		{
			line[i++] = '0';
			line[i] = 0;
			return i;
		}
 
		if (num < 0 && base == 10)
		{
			isNegative = true;
			num = -num;
		}
 
		while (num != 0)
		{
			int rem = num % base;
			line[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
			num = num/base;
		}
		if (isNegative) line[i++] = '-';
		line[i] = 0;
		reverse(line, i);
		return i;
	}

	int to_float( char *line, float fnum )
	{
		char f1[20] = "", f2[20] = "";
		bool isnegative = 0;
		if( fnum < 0.0 ) 
		{
			fnum *= -1.0;
			isnegative = 1;
		}
		int num = (int)fnum;
		int lnum = to_num( f1, num );
		fnum -= (float)num;
		int a, d = 0;
		int rnum = 6 - lnum;
		if( lnum == 1 && f1[0] == '0' ) rnum--;
		int i = 0;
		float add = 0.5f;
		if( rnum == 0 ) 
		{
			fnum *= 10.0f;
			if( int(fnum) + '0' > '4') f1[lnum - 1]++;
		}
		else
		{
			for( a = 0; a < rnum; a++ ) add /= 10.0f;
			fnum += add;
		}
		for( a = 0; a < rnum; a++ )
		{
			fnum *= 10.0f;
			d = int(fnum);
			f2[i] = '0'+ d;
			fnum -= (float)d;
			i++;
		}
		int l = 0;
		if( isnegative ) { line[l] = '-'; l++; }
		for( a = 0; a < lnum; a++ ) { line[l] = f1[a]; l++; }
		line[l] = '.'; l++;
		for( a = 0; a < i; a++ ) { line[l] = f2[a]; l++; }
		for( a = l - 1; a >= 0; a-- )
		{
			if( line[a] != '.' && line[a] != '0' ) break;
			line[a] = 0;
			l--;
		}
		return l;
	}


1
2
3
4
5
6
7
8
9
10
11
int _tmain(int argc, _TCHAR* argv[])
{
	char s[64] = "";
	cout << "s:" << s << endl;
	float u = 123456.47f;
	cout << "float:" << u << endl;
	str::to_float(s, u);
	cout << "s:" << s << endl;
	system("PAUSE");
	return 900; 
}


1
2
3
s:
float:123456
s:123456


The function i made is working fine, exacly how cout << float is working.
The problem is i think my function is not really effective.
By that i mean my function is doing alot of useless stuff to do what i want
and there have to be a better way.

Can you guys improve my code?
The rule is that you can not use other functions, only
playing with loops and operators.

Thank you!
Last edited on
Well, I didn't really get to look through all of your code, but one thing I notice right off the bat is that your to_float() function returns an integer. Change it to return a float.
It returns the size of the string.
for example 123456 string size is 6, that what it should return.

My code does the same thing as:
snprintf( line, linesize, "%f", 123456.47f );
my function is doing alot of useless stuff
It does not do even half of the stuff it should.

How it handles large exponents? Subnormal numbers? Infinities? NaN (both quiet and signalling)? Does it loses precision? Will it work if decimal point separator is comma? If current locale specifies specific grouping for digits?

Here is actual code from glibc which is used when you want to pring floating poin numbers with printf function family:
http://code.woboq.org/userspace/glibc/stdio-common/printf_fp.c.html
(and 2011 version was 2300 lines long)
Last edited on
I see where this is going ... hm
I think i should learn the structure of float ( stored as bytes )

for example int is 4 bytes
b[4] = 0 0 0 35 = 34
b[4] = 0 0 0 255 = 255
b[4] = 0 0 1 1 = 257
so the formula would be something like this:
int = b[0] + ( b[1] * 256)+( b[2] * (256*256)) +( (256*256*256) * b[3] )

But for floats ... after testing how they are stored the numbers didin't make any sense to me. I readed online yet still didin't got any information what would help me to understand this thing.

i was guessing that float were stored not much differently than ints but somewhere in b[4] there is data what shows the place of '.'

my idea was that b[0-3] is exactly the as in ints and the final byte,
half ( 4bits ) of its data for '.' pos and other half ( 4bits ) for value.

but after testing that idea, i was wrong once again.
Can someone link me to source where i can learn how floats and doubles are stored?

Thanks!



http://en.wikipedia.org/wiki/Single-precision_floating-point_format
This is wikipedia article on single precision IEEE 754 floating point number (float in common C++ implementations). It shows layout of number in memory. Also it describes special cases of floating point numbers.
Topic archived. No new replies allowed.