PDA

View Full Version : Number to Text, C++


Xerxes
03-29-2006, 12:20 AM
So:


//This code is public domain because it took so little time to write.
//But it doesn't work well with really large numbers.

#include <iostream.h>

//Main is recursive, code is pretty improper. If sizeof(int*)!=sizeof(int) for you,
//it probably won't work. Just change main's name, every call to main to a call to
//the new main, and the int in main to char*, and get rid of all the char* and int
//typecasts and you would've made it a lot more proper.

//This puts two strings together.
char *sadd(char *s1, char *s2) {
char *res;
int s1len=0;
int s2len=0;
for (;s1[s1len]!='\0';s1len++) {}
for (;s2[s2len]!='\0';s2len++) {}
int rlen=s1len+s2len;
res=new char[rlen+1];
for (int x=0;x<s1len;x++) { res[x]=s1[x]; }
for (int x=0,y=s1len;y<rlen;x++,y++) { res[y]=s2[x]; }
res[rlen]='\0';
return res;
}

//Main. Set start to 1 if you want it to
//query the user or 0 if you want it to
//return a pointer to num made into
//words.
//Get rid of start, the first parameter in every call to this
//function, and the if (start) { } else part of it and a bracket at
//the end if you want to make use of this function.
int main(bool start, __int64 num) {
if (start) { //if it's the first time calling the function...
while(1) {
cout << "Input number(zero to quit): ";
__int64 num;
cin >> num;
system("cls");
if (num==0) {
//A pretty damn stupid way to quit.
int zero=0; //Because warnings piss me off.
int blah=0/zero;
}
char *ans=(char*)main(0,num);
cout << ans << "\n";
delete[] ans;
}
} else { //, otherwise...
char *res;
if (num<0) { //Negative numbers get a "negative" in front of them and then their positive words.
char *p1=(char*)main(0,0-num);
res=sadd("negative \0",p1);
delete[] p1;
return (int)res;
}
if (num<20) { //These can't get any simpler.
if (num==0) { res="zero\0"; }
if (num==1) { res="one\0"; }
if (num==2) { res="two\0"; }
if (num==3) { res="three\0"; }
if (num==4) { res="four\0"; }
if (num==5) { res="five\0"; }
if (num==6) { res="six\0"; }
if (num==7) { res="seven\0"; }
if (num==8) { res="eight\0"; }
if (num==9) { res="nine\0"; }
if (num==10) { res="ten\0"; }
if (num==11) { res="eleven\0"; }
if (num==12) { res="twelve\0"; }
if (num==13) { res="thirteen\0"; }
if (num==14) { res="fourteen\0"; }
if (num==15) { res="fifteen\0"; }
if (num==16) { res="sixteen\0"; }
if (num==17) { res="seventeen\0"; }
if (num==18) { res="eightteen\0"; }
if (num==19) { res="nineteen\0"; }
return (int)res;
} if (num<100) { //Ten's place.
__int64 bnum=num/10;
__int64 snum=num-(bnum*10);
if (snum==0) {
if (bnum==2) { res="twenty\0"; }
if (bnum==3) { res="thirty\0"; }
if (bnum==4) { res="fourty\0"; }
if (bnum==5) { res="fifty\0"; }
if (bnum==6) { res="sixty\0"; }
if (bnum==7) { res="seventy\0"; }
if (bnum==8) { res="eighty\0"; }
if (bnum==9) { res="ninety\0"; }
return (int)res;
}
char *p2=(char*)main(0,snum);
if (bnum==2) { res=sadd("twenty \0",p2); }
if (bnum==3) { res=sadd("thirty \0",p2); }
if (bnum==4) { res=sadd("fourty \0",p2); }
if (bnum==5) { res=sadd("fifty \0",p2); }
if (bnum==6) { res=sadd("sixty \0",p2); }
if (bnum==7) { res=sadd("seventy \0",p2); }
if (bnum==8) { res=sadd("eighty \0",p2); }
if (bnum==9) { res=sadd("ninety \0",p2); }
delete[] p2;
return (int)res;
}
if (num<1000) { //Hundred's place
__int64 bnum=num/100;
__int64 snum=num-(bnum*100);
char *bnum_c=(char*)main(0, bnum);
if (snum>0) {
char *snum_c=(char*)main(0, snum);
res=sadd(sadd(bnum_c," hundred \0"), snum_c);
delete[] snum_c;
} else {
res=sadd(bnum_c," hundred\0");
}
delete[] bnum_c;
return (int)res;
}
__int64 a=1; //All the other places..
__int64 d=0;
for (;num>=a*1000;a*=1000,d++) {}
char *ttl;
if (d==1) { ttl="thousand\0"; }
if (d==2) { ttl="million\0"; }
if (d==3) { ttl="billion\0"; }
if (d==4) { ttl="trillion\0"; }
if (d==5) { ttl="quadrillion\0"; }
if (d==6) { ttl="quintillion\0"; }
if (d==7) { ttl="sextillion\0"; } //If you want to add some more, there's a pattern.. Too high to matter much, though. And you'd need to combine a couple ints.
__int64 bnum=num/a;
__int64 snum=num-(bnum*a);
char *bnum_c=(char*)main(0, bnum);
if (snum>0) {
char *snum_c=(char*)main(0, snum);
res=sadd(sadd(bnum_c,sadd(" \0",sadd(ttl," \0"))), snum_c);
delete[] snum_c;
} else {
res=sadd(bnum_c,sadd(" \0",ttl));
}
delete[] bnum_c;
return (int)res;
}
}

const bool nothing=main(1,0); //As close to just calling it as I could get.



Just type it in and it'll tell you what it is.

Should support integers from -2^63-1 to 2^63-1, but doesn't.

EDIT: Fixed it up a little.

phreak
03-29-2006, 11:42 PM
Nice code but not particularly efficient in my opinion (then again, I would have learnt assembler if speed's what I was after)

Here's my quick algorithm for the thing, which is non-working since I haven't programmed for years, and don't feel like actually doing everything right now, but you'll get the idea. Also, STL is helpful with these things, its string manipulations are really nice for lazy people like me.


#include <stdlib.h>
#include <math.h>
#include <iostream.h>


array digit("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"..."nineteen");
array twodigit("twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety");
array suffix("hundred", "thousand", "million", etc);

div_t temp; //helper thingy

char *answer;
input(n)
if (n<0) {answer="negative "; n=abs(n) } //do away with the negative number

for (long int x=floor(log10(n)); x=>2; x--){ //find the number of digits(x+1) and itterate down to 2.

temp = div( n, 10^x ); //quick way of finding the digit at place x+1
n=temp.rem; //replacing n for next iteration
if (temp.quot!=0){
answer=answer+" "+digit[temp.quot]+" "+suffix[x-2];
}
}
// this is the basic idea. for this thing to work, it should be broken down into cycles of three, which is easy. Just do three digits at a time, starting the loop at the biggest multiple of 3 that is smaller than the number of digits.


Cheers :cool: