LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Can I use a lot of decimals in my C program? (https://www.linuxquestions.org/questions/programming-9/can-i-use-a-lot-of-decimals-in-my-c-program-200051/)

Golradir 07-01-2004 04:12 PM

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? :newbie:

Golradir 07-01-2004 04:13 PM

WTF is this doing here? I thought I posted it in the programming forum... Can some mod please move it?

XavierP 07-01-2004 05:04 PM

Moved to Programming

Dark_Helmet 07-01-2004 05:37 PM

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

Hko 07-01-2004 06:37 PM

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.

Dark_Helmet 07-01-2004 07:12 PM

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>

Hko 07-02-2004 04:56 AM

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.

Hko 07-02-2004 05:16 AM

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.

Dark_Helmet 07-02-2004 11:53 AM

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?

Hko 07-03-2004 05:50 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.

Golradir 07-03-2004 06:04 AM

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!

aluser 07-03-2004 03:00 PM

If you're on a linux box there's bc, which should do what you want without programming anything.

aluser 07-03-2004 03:05 PM

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.

Golradir 07-03-2004 03:52 PM

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.

hcgernhardt 07-04-2004 12:40 PM

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


All times are GMT -5. The time now is 03:40 AM.