ntoa (number to ascii)

I'm making a templated function to convert a number of any type to a string. Logically it should work, but it doesn't. Does anyone see anything wrong?

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
#include <cstdio>
#include <string>
using std::string;

template<typename T>
string& ntoa(T n,string& a){
	bool dot=false;
	T temp;
	if(n<0){
		a+='-';
		n=-n;}
	while(n>T(0.000000)){
		printf("n: %f\n",n);//for debugging purposes
		a+=char(unsigned(n)-unsigned(n/10)*10)+'0';
		if(dot){
			n-=unsigned(n)-unsigned(n/10)*10;
			n*=10;}
		else{
			temp=T(unsigned(n));
			temp-=unsigned(n)-10*unsigned(n/10);
			temp/=10;
			n=T(unsigned(temp))+n-T(unsigned(n));}//n=ipart(temp)+fpart(n)
		if(n<1 && n>0 && !dot){
			a+='.';
			n*=10;
			dot=true;}}
	return a;}

int main(){
	string str;
	double num=33.14159265;
	ntoa(num,str);
	printf("%s",str.c_str());
	getchar();
	return 0;}
n: 33.141593
n: 3.141593
n: 1.415926
n: 4.159265
n: 1.592650
n: 5.926500
n: 9.265000
n: 2.650000
n: 6.500000
n: 5.000000
n: 10.000000
n: 9.999998
n: 9.999976
n: 9.999765
n: 9.997645
n: 9.976453
n: 9.764532
n: 7.645318
n: 6.453182
n: 4.531822
n: 5.318217
n: 3.182171
n: 1.821711
n: 8.217110
n: 2.171099
n: 1.710989
n: 7.109889
n: 1.098888
n: 0.988879
n: 9.888792
n: 8.887920
n: 8.879204
n: 8.792038
n: 7.920380
n: 9.203796
n: 2.037964
n: 0.379639
n: 3.796387
n: 7.963867
n: 9.638672
n: 6.386719
n: 3.867188
n: 8.671875
n: 6.718750
n: 7.187500
n: 1.875000
n: 8.750000
n: 7.500000
n: 5.000000
33.14159264999999976453182171098887920379638671875

I tried to avoid the commonly used top-down approach (use log10 to find the most significant digit) to allow for larger user-defined data types. Can anyone see the problem with it?
Have you considered using std::stringstream?
I'd rather not. I'd rather keep the dependencies down to a minimum. Plus, stringstream doesn't support user-defined number types unless they overload the << >> operators, does it?
^No it doesn't, but I don't see a problem since printf() doesn't and can't ever.
I'm just using cstdio for I/O. After this function is complete, I'm going to add it to my string class.
Those casts to unsigned could easily overflow.
Machine precision, that's your problem.
I'm not sure that your function will always end, either.

Edit: what is happening to the date of the posts?
Last edited on
So would you suggest that I use math.h's floor function and make floor functions for the integer types? Or is there an easy algorithm to floor any number type?

Also on note of machine precision, how should I fix it?
If you are going to specialize for integers, then just use operator% (for floating point fmod)
Also, the integer part of your string is reversed.

Edit: I think it will be better to specialize for floating, and use % in the template version

About the precision, maybe a fixed numbers of decimals [and using scientific notation]
Last edited on
Topic archived. No new replies allowed.