LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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

Reply
 
Search this Thread
Old 07-01-2004, 04:12 PM   #1
Golradir
LQ Newbie
 
Registered: Mar 2004
Posts: 27

Rep: Reputation: 15
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.
 
Old 07-01-2004, 04:13 PM   #2
Golradir
LQ Newbie
 
Registered: Mar 2004
Posts: 27

Original Poster
Rep: Reputation: 15
WTF is this doing here? I thought I posted it in the programming forum... Can some mod please move it?
 
Old 07-01-2004, 05:04 PM   #3
XavierP
Moderator
 
Registered: Nov 2002
Location: Kent, England
Distribution: Lubuntu
Posts: 19,174
Blog Entries: 4

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Moved to Programming
 
Old 07-01-2004, 05:37 PM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
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
 
Old 07-01-2004, 06:37 PM   #5
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
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.
 
Old 07-01-2004, 07:12 PM   #6
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
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 <stdio.h>

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...

<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.
 
Old 07-02-2004, 04:56 AM   #7
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
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 <stdio.h>

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.
 
Old 07-02-2004, 05:16 AM   #8
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
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.
 
Old 07-02-2004, 11:53 AM   #9
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
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
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.
 
Old 07-03-2004, 05:50 AM   #10
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
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.
 
Old 07-03-2004, 06:04 AM   #11
Golradir
LQ Newbie
 
Registered: Mar 2004
Posts: 27

Original Poster
Rep: Reputation: 15
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!
 
Old 07-03-2004, 03:00 PM   #12
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
If you're on a linux box there's bc, which should do what you want without programming anything.
 
Old 07-03-2004, 03:05 PM   #13
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
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.
 
Old 07-03-2004, 03:52 PM   #14
Golradir
LQ Newbie
 
Registered: Mar 2004
Posts: 27

Original Poster
Rep: Reputation: 15
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.
 
Old 07-04-2004, 12:40 PM   #15
hcgernhardt
LQ Newbie
 
Registered: Apr 2004
Distribution: Slackware
Posts: 29

Rep: Reputation: 15
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
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to compare decimals linuxboy69 Linux - Software 2 08-16-2004 02:43 PM
A LOT of files NetScripter Linux - General 3 08-22-2003 12:54 PM
Thanks a Lot! XPediTioN Slackware 0 07-11-2003 04:51 PM
There's a lot of Stephanies about... stephstellar General 3 02-03-2003 07:11 AM
Learned a lot!!!! LinuzRulz Linux - Software 2 03-05-2002 08:39 AM


All times are GMT -5. The time now is 09:20 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration