ttmath UInt to string?

Sep 18, 2010 at 6:40pm
Hi all

First of all I am using a c++ library ttmath, and I have a problem. I have a really big number declared like this:

ttmath::UInt<20> big1;

And I am calculating the number "100!".

It comes out as cca. 160 digit number, and now I have to add up all the single numbers, to get the total sum. So what I want to do is convert this to a string and then simply add up all the chars, simple right? The only thing not simple (since I am new to the library) is converting the number to a string (if at all possible). Now since it's a pretty long shoot to find somebody here who is such an expert at this library, I will also ask for any suggestions using some other techniques, to access the data, or for any other libraries where this task is possible, hopefully trivial with a ToString() function :)

Thanks
Last edited on Sep 18, 2010 at 6:41pm
Sep 18, 2010 at 6:58pm
Hehehe, I'm so stupid :P, I just copy-pasted the text, and then made a string by hand :P
Ok, so now the problem is solved, but I would still like to know if this can be done in a normal fashion.
Sep 18, 2010 at 7:05pm
I use this library too :D
1
2
3
4
5
6
7
template<typename NumTy>
string String(const NumTy& Num)
{
	stringstream StrStream;
	StrStream << Num;
	return(StrStream.str());
}


Then call it like this: string MyString = String<ttmath::UInt<20> >(big1);
Last edited on Sep 18, 2010 at 7:06pm
Sep 18, 2010 at 7:34pm
Waw :D Sweeeeeet.

Man I really got go over these templates one day. What does this template do (the one you wrote)??

And thanks a lot man :)
Sep 18, 2010 at 7:47pm
In this case, it lets you use the String() function to convert any type of number/class to a string (if, of course, the class supports stringstreams and << and >> for going to/from stringstreams)

You could remove the template part of it, but then you would have to make a different version of the function for each type you would want to convert to a string.

http://www.cplusplus.com/doc/tutorial/templates/
Last edited on Sep 18, 2010 at 7:47pm
Sep 18, 2010 at 7:47pm
Another thing came up, do you have any idea, how or where to store 1000^1000?
Sep 18, 2010 at 7:53pm
Well, apparently ttmath doesn't yet have ^ or ^= operators yet.

For the integer types, I just wrote some code to multiply in a loop. Here is a sample of some code from my project:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SInt1024 Pow = /* Power */;
	if(Pow > 0)
	{
		SInt1024 Temp = rdPtr->SuperSInt;
		for(SInt1024 i = Pow; i > 1; i--)
		{
			rdPtr->SuperSInt *= Temp;
		}
	}
	else if(Pow < 0)
	{
		SInt1024 Temp = rdPtr->SuperSInt;
		rdPtr->SuperSInt = 1;
		for(SInt1024 i = Pow; i < 0; i++)
		{
			rdPtr->SuperSInt /= Temp;
		}
	}
	else
	{
		rdPtr->SuperSInt = 1;
	}


rdPtr->SuperSInt is the base.

I wasn't going for max efficiency so I didn't write more efficient code than this, even though there is a better way to do this.
Last edited on Sep 18, 2010 at 7:54pm
Sep 18, 2010 at 8:00pm
This is the algorithm for calculating the numbers, but my question is, where to store the numbers of such huge proportions. ttmath::UInt<?>, this puppy would probably crumble, and I don't even know how big of a number would have to go in the <>, 1000, 3000, 10000, a gazillion, :P.
Sep 18, 2010 at 8:12pm
http://paste.pocoo.org/show/263693/

Just do a few range tests and see what has a larger range than that. As a starting base, I used a 2kb number (16384 bits) to calculate that. (probably overkill) You can go down from there. ;)

Remember the ttmath macro TTMATH_BITS(/*number of bits to use*/) which can go in the <>
Last edited on Sep 18, 2010 at 8:13pm
Sep 18, 2010 at 8:42pm
But the ttmath::UInt will be able to handle it? (since in the FAQ it says that it is not meant to store more then <100> cuz it puts the data on the stack) (I don't know why I'm asking why I don't just try it :P). But I will ask you what you mean with "Just do a few range tests and see what has a larger range than that."?

EDIT: and what is SInt1024
Last edited on Sep 18, 2010 at 8:44pm
Sep 18, 2010 at 8:51pm
juvan wrote:
EDIT: and what is SInt1024

It's just a typedef I made: typedef ttmath::Int<TTMATH_BITS(1024)> SInt1024;

And by doing a few range tests, I mean use an unsigned type and set it to 0, then subtract one from it. If you then print the number, that will be the highest number it can represent.

Here is the concept using a char as an example:
1
2
3
unsigned char Num = 0;
--Num;
cout << Num; //Prints 255 
Sep 18, 2010 at 8:55pm
Oooo nice one :)
Didn't even think about that one. Well I'm glad to say that it all works.

Thanks for all your help. I'll be seeing you around (maybe in 5-10 mins if I get stuck again)

Sep 21, 2010 at 12:33am

@juvan
So what I want to do is convert this to a string and then simply add up all the chars, simple right?


1
2
3
	ttmath::UInt<20> big1;
	std::string res;
	big1.ToString(res);



@juvan
UInt<100> on a 32 bit machine can store (2^(32*100) - 1) as a max value.


1
2
3
	ttmath::UInt<100> big1;
	big1.SetMax();
	std::cout << big1 << std::endl;




@LB
Well, apparently ttmath doesn't yet have ^ or ^= operators yet.


Operator ^ is a bitwise xor, use Pow method instead.

1
2
3
4
5
	ttmath::UInt<20> big1, big2;
	big1 = 1000;
	big2 = 1000;
	big1.Pow(big2);
	std::cout << big1 << std::endl;

Sep 21, 2010 at 1:46am
Just do a few range tests and see what has a larger range than that. As a starting base, I used a 2kb number (16384 bits) to calculate that. (probably overkill) You can go down from there. ;)


There's a simple formula.

Given the number x^y in base 10, the number of bits needed to store this number is

ceil( y * log( 10 ) / log( 2 ) )
Topic archived. No new replies allowed.