Go Job Hunting at the LQ Job Marketplace
 Home Forums HCL Reviews Tutorials Articles Register Search Today's Posts Mark Forums Read
 LinuxQuestions.org Can I use a lot of decimals in my C program?
 Programming This forum is for all programming questions. The question does not have to be directly related to Linux and any language is fair game.

Notices

 07-01-2004, 04:12 PM #1 Golradir LQ Newbie   Registered: Mar 2004 Posts: 27 Rep: Can I use a lot of decimals in my C program? 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? Last edited by Golradir; 07-01-2004 at 04:18 PM.
 07-01-2004, 04:13 PM #2 Golradir LQ Newbie   Registered: Mar 2004 Posts: 27 Original Poster Rep: WTF is this doing here? I thought I posted it in the programming forum... Can some mod please move it?
 07-01-2004, 05:04 PM #3 XavierP Moderator   Registered: Nov 2002 Location: Kent, England Distribution: Lubuntu Posts: 19,181 Blog Entries: 4 Rep: Moved to Programming
 07-01-2004, 05:37 PM #4 Dark_Helmet Senior Member   Registered: Jan 2003 Posts: 2,786 Rep: 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. For details: man 3 printf
 07-01-2004, 06:37 PM #5 Hko Senior Member   Registered: Aug 2002 Location: Groningen, The Netherlands Distribution: ubuntu Posts: 2,530 Rep: 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.
 07-01-2004, 07:12 PM #6 Dark_Helmet Senior Member   Registered: Jan 2003 Posts: 2,786 Rep: 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: contents of simple.c: Code: ```#include int main() { double test_val; test_val = 1.2 / 1e+50; printf( "test_val = %e\n", test_val ); return 0; }``` \$ gcc -o simple simple.c \$ ./simple test_val = 1.200000e-50 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... 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 Last edited by Dark_Helmet; 07-01-2004 at 07:42 PM.
07-02-2004, 04:56 AM   #7
Hko
Senior Member

Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep:
Quote:
 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: Code: ```#include int main() { double test_val; test_val = 1.2 / 1e+50; printf( "test_val = %e\n", test_val ); return 0; }``` \$ gcc -o simple simple.c \$ ./simple test_val = 1.200000e-50
IMO that's not a fair test at all. Try this instead:
Code:
```#include <stdio.h>

int main()
{
double test_val;

test_val = 1.0/3.0;
printf( "test_val = %.20e\n", test_val );
return 0;
}```
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.

 07-02-2004, 05:16 AM #8 Hko Senior Member   Registered: Aug 2002 Location: Groningen, The Netherlands Distribution: ubuntu Posts: 2,530 Rep: In my first post in this thread I forgot to mention that you can do HUGE floating point numbers as well with "gmp". Not only integers.
07-02-2004, 11:53 AM   #9
Dark_Helmet
Senior Member

Registered: Jan 2003
Posts: 2,786

Rep:
Quote:
 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
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.

 07-03-2004, 05:50 AM #10 Hko Senior Member   Registered: Aug 2002 Location: Groningen, The Netherlands Distribution: ubuntu Posts: 2,530 Rep: 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.
 07-03-2004, 06:04 AM #11 Golradir LQ Newbie   Registered: Mar 2004 Posts: 27 Original Poster Rep: 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!
 07-03-2004, 03:00 PM #12 aluser Member   Registered: Mar 2004 Location: Massachusetts Distribution: Debian Posts: 557 Rep: If you're on a linux box there's bc, which should do what you want without programming anything.
 07-03-2004, 03:05 PM #13 aluser Member   Registered: Mar 2004 Location: Massachusetts Distribution: Debian Posts: 557 Rep: oh, and of course you could get the source to bc and check how it does it I also remember that there is a library with openssl that handles large numbers, but possibly just integers.
 07-03-2004, 03:52 PM #14 Golradir LQ Newbie   Registered: Mar 2004 Posts: 27 Original Poster Rep: Thanks aluser, bc works fine! I've read that you can also use bc in a program, so I don't have to type al the calculations in bc itself.
 07-04-2004, 12:40 PM #15 hcgernhardt LQ Newbie   Registered: Apr 2004 Distribution: Slackware Posts: 29 Rep: 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. Good luck, Henry