How to print very large numbers to file?

Posted By: tolu619

How to print very large numbers to file? - 07/18/14 23:30

I have a program that handles simulation of the Ideal Gas Law (from physics and chemistry). The number of gas molecules at anytime is the number of moles of gas (usually less than 20 in my software) multiplied by Avogadros number (602210000000000000000000). The final value is displayed properly by a digit on-screen, but whenever I try to print it to a text file, it ends up printing some number, usually between 6 to 8 digits, that doesn't even seem related to the number of molecules.
It isn't a case of deleted trailing zeroes or an omission to multiply one of the two variables....I'm sure I'm doing something wrong.

Code:
var n = 0.9863; //moles

STRING* Molecules = str_create("\nNumber of Molecules: ");
	var Number = n * 602210000000000000000000;
	str_cat_num(Molecules, "%.0f", Number); //I've tried various combos here
        STRING* Moles = "\nwhich is ";
	str_cat_num(Moles, "%.0f mole(s) of gas", n);

Posted By: Talemon

Re: How to print very large numbers to file? - 07/20/14 10:33

var has a range of about -999999.999..+999999.999 which is not suitable for your calculations. You should make your calculations using double typed variables and use str_printf to convert them to displayable strings.
Posted By: WretchedSid

Re: How to print very large numbers to file? - 07/20/14 17:24

A double?

A double has a 52 bit mantissa and can therefore hold integers up to 2^53 before losing precision, as in you would stop being able to accurately represent them perfectly.

Anything multiplied by 602210000000000000000000 is way out of a doubles range, even out of a long doubles range.

@tolu619: I think you are picking the wrongest tool for the job here. Maybe Mathematica would be more suitable for your needs? The alternative is that you roll your own integer type that has enough bits for your needs. If 20 * 602210000000000000000000 is the highest number you'll have, you need at least 85 bits to store it.
Posted By: Superku

Re: How to print very large numbers to file? - 07/20/14 18:04

Just base your calculations on a factor of 60221 and add zeros in the string:

str_cat_num(Moles, "%.0f0000000000000000000 mole(s) of gas", n);
Posted By: tolu619

Re: How to print very large numbers to file? - 07/25/14 19:24

Originally Posted By: Superku
Just base your calculations on a factor of 60221 and add zeros in the string:

str_cat_num(Moles, "%.0f0000000000000000000 mole(s) of gas", n);
\

Thanks!
@JustSid, wow, I hadn't even considered the possibility of making my own special data type. I'd have to use a struct for that right? I'll go with Superku's suggestion
Posted By: tolu619

Re: How to print very large numbers to file? - 07/25/14 19:32

AH! Anyone have any sample code for creating a variable with an 85-bit mantissa? I tried Superku's idea before I realized that adding "0000000000000000000" to the end of a printed string won't give me the same result as multiplying by 602210000000000000000000
Posted By: WretchedSid

Re: How to print very large numbers to file? - 07/28/14 20:32

Sorry, I totally forgot about this post.

You can't create a 85 bit integer, but you can create an 88 bit integer (that's 11 bytes, if anyone keeps count). You don't necessarily need a struct for this, but you can use one. You really only need a contiguous block of 11 bytes of memory though.

Addition is fairly easy. Start with the least significant bit and and move up to the most significant bit, add the bits up and overflow to the left when necessary.

Multiplication can simply be implemented by repeatedly adding numbers (surprise, hu?)

Tricky is the printing part, because you need division and modulo for that. Here is a paper from Microsoft Research about integer division.

Once you have that in place, you take the modulo of the number and the 10, add that to the result string and divide the number by 10. Rinse and repeat until your number is 0. I've implemented something like this for my Firedrake kernel, it allows the usage of an arbitrary base, but you can simplify it if you need base 10 only: https://github.com/JustSid/Firedrake/blob/rewrite/lib/libc/stdlib.c#L56-L92
© 2024 lite-C Forums