ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Welcome to LinuxQuestions.org, a friendly and active Linux Community.

You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!

Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.

Hello! First of all let me tell you I am a real newbie to C. I must have a program for school that is able to calculate with say 50 to 100 decimals, but the normal calculator stops at 10 decimals. Is this possible with C, or do I have to use C++? The only variables I know which are able to store decimals are float and double, but they are only able to store 6 decimals...Could you please help me?

The problem is not with the float or double data types, it's the conversion string you used in printf(). I assume you did something like:

printf( "variable = %f\n", variable );

The %f conversion specifier defaults to 6 decimal places if you so not specify it. You can modify that by saying something like:

printf( "variable = %55.50f\n", variable );

This tells printf to display the number using a space 55 characters wide. The 50 (following the dot/period/decimal point) tells printf to display 50 digits to the right of the decimal when displaying the number. Note that this format will *always* print 50 decimal places even if the value you want to display is 1.0, 0.1, or something similar.

You can also use the %e specification. This will cause your number to be printed in scientific notation.

The standard types in C are not enough for numbers that big. Using "double" you can store huge numbers, but stll with limited precision: you don't get all the digits, and they are floating point numbers, not integers.

To use really HUGE integers (up to several thousands of digits) you can link your C program with the gmp-library (gcc ... -lgmp ...). You may need to install its package (and its the libgmp-dev or libgmp-develop companion) from your distribution.

Then type "info gmp" in a terminal and read about it.

I'm not quite sure I agree with you Hko. The double data type is more than capable of representing a number with 50 or more decimal places. For instance:

I would have to go back and look at some docs to see exactly how the double data type is partitioned. I will agree that a double cannot represent a continuous string of 50 or more non-zero digits in a single number, but it can represent a number "located" 50 digits passed the decimal point. Not trying to be a "rules lawyer" but it is an important distinction. The resolution of a double may be limited, but it can represent a vast range of values.

Given that this was school work (which I assumed was a high school level), I didn't think constructing your own integer/floating point data structure/class would be involved.

I guess what I'm trying to say is, we'd need more details about the nature of the programming project because Hko and my replies are valid in a given context.

note: sorry, I'm in one of my defensive moods...

<edit>
Clarification: "string 50 or more non-zero digits" ought to be "string of digits whose first and last non-zero digits are separated by 48 or more digits"... In other words, the system would likely say that 1.0 + 1.0e-50 = 1.0
</edit>

Last edited by Dark_Helmet; 07-01-2004 at 07:42 PM.

Originally posted by Dark_Helmet
I'm not quite sure I agree with you Hko. The double data type is more than capable of representing a number with 50 or more decimal places. For instance:

It's already wrong at the 17th digit. With other calculations it may fail even earlier.

Quote:

I will agree that a double cannot represent a continuous string of 50 or more non-zero digits in a single number, but it can represent a number "located" 50 digits passed the decimal point.

Yes. It can represent even a lot more digits, but they will be wrong...

Quote:

I guess what I'm trying to say is, we'd need more details about the nature of the programming project because Hko and my replies are valid in a given context.

Yes, I agree fully with that.

Quote:

note: sorry, I'm in one of my defensive moods...

No offense taken A healthy discussion is what this forum is for IMHO.

Originally posted by Hko
Yes. It can represent even a lot more digits, but they will be wrong...

Not necessarily. I should have clarified the statement a little more. By "located" I mean the most significant digit of the number is located 50 digits beyond the decimal point, or within X digits of that 50th digit. X depends on the organization of the float. If I remember correctly, the float uses three bytes for the significand, and one byte for the exponent. In other words (a very rough estimate) means the float can represent any number between -8,000,000 and +8,000,000 shifted by an exponent ranging from -127 to +128. So, if the first non-zero value is located at roughly the 44th digit past the decimal (or later), then the 50th digit will be accurate. A double would modify that range even more (I think it's 6:2 ratio of bytes in significand to bytes in exponent).

If the project needs arbitrary accuracy to the nth digit, then this information is not applicable. If, however, the project is willing to accept some limitation on accuracy, then the standard floats and doubles will work. It could be boiled down to this (from Hko's code):

1.0 / 3.0
Chose which answer you want:
1. digit '3' at every location in the number displayed => use custom data types
2. digit '3' displayed for roughly 7/14 digits => use float/double respectively

And I guess that really boils down to: does the project need to accurately represent 1.0 + 1e-15, or is the difference in magnitude enough to simply ignore the smaller number?

Last edited by Dark_Helmet; 07-02-2004 at 11:54 AM.

Yes, you're right about that a double can represent the 50th digit correctly if about the first 35 digits are zeroes after the decimal point, i.e. 0.0000000000000000000000000000000000000000.

And yes, It's not clear enough what the original poster needs, to say something applicable.

I don't need something like 1.3 E -50, I really need all the decimals. A normal calculator gives me 1.3 E -50, that's why I need my own program... (I am trying to make some calculations about gravity assist). I tried a to work a little bit with GMP, but it doesn't really work, so I will need to read more on it... Thanks for all the advice!

Okay. So what you're saying is you want to calculate a number using an arbitrary precision---that is to say a mantissa of an arbitrary length (in your example, a mantissa of 50 to 100 decimal digits).

For that, my friend, I would suggest you use a mathematical analysis program, such as Maple or GnuCalc. GnuCalc has the advantage of being free, although it's been several years since I've even attempted to use it, and have not tried to find if it has a gui front end.

LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.