4

I am writing a program in which I need to store numbers with a very high precision(around 10^-10) and then further use them a parameter( create_bloomfilter ([yet to decide the type] falsePositivity, long expected_num_of_elem) ).
The highest precision I am able to get is with double (something around 10^-6) which is not sufficient.

How can we store numbers with more higher precision in c?

Aman Deep Gautam
  • 8,091
  • 21
  • 74
  • 130
  • 1
    Reframe your Q to say you want to store numbers with higher ***precision***, Merely saying ***small number*** doesn't make much sense really. – Alok Save Jun 20 '12 at 07:13
  • You need to specify a range. Also, how you want to handle holes near zero, rounding etc. – dirkgently Jun 20 '12 at 07:15
  • @DietrichEpp I ran it on my system and if I put 10^-7 it is printing 0 as value and format string I used was `%lf`. – Aman Deep Gautam Jun 20 '12 at 07:20
  • I edited the Q for you.Check if that is what you want to ask, Also fill in the detail I left open for you in *italics*. – Alok Save Jun 20 '12 at 07:22
  • 1
    @AmanDeepGautam: What is the largest possible value for that number? Since precision for floating point number is defined in "number of digits", not absolute value. – nhahtdh Jun 20 '12 at 07:30
  • @nhahtdh I do not care for the largest value in this case. It can be as small as `1` for instance – Aman Deep Gautam Jun 20 '12 at 07:32
  • @AmanDeepGautam: I do care, since the answer can be simply `double` type or `BigDecimal` kind of library. – nhahtdh Jun 20 '12 at 07:34
  • @nhahtdh what I meant 'by do not care' is that you can keep it as you wish, I put no constraints on upper limit as that is not what I will be worried about. – Aman Deep Gautam Jun 20 '12 at 07:41
  • @AmanDeepGautam: If the number is 10^10, then you won't get the precision down to 10^-10, since the precision of double is only 16 digits. – nhahtdh Jun 20 '12 at 07:43

3 Answers3

5

You have been misinformed about double.

The smallest positive number you can store in a double is about 2⨯10-308, not counting denormalized numbers, which can be smaller. Denormals go down to 5⨯10-324. They have the equivalent of about 15-17 digits of precision, which is sufficient to measure the diameter of the Earth to within the size of a red blood cell, the smallest cell in the human body.

If you really need more precision, you need MPFR. (If your algorithms are numerically unstable, MPFR might not help.)

Edit: I figured out what you are doing wrong.

In C, 10^-7 is an integer expression. It should be equal to -13 on most systems. The ^ operator is the bitwise XOR operator, not the exponentiation operator. There is no exponentiation operator in C, because C operators generally correspond to more primitive operations, at least in terms of hardware implementation.

You want 1e-7, or pow(10, -7).

#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{
    printf("2e-308 = %g\n", 2e-308);
    printf("2 * pow(10, -308) = %g\n", 2 * pow(10, -308));
    printf("10^-7 = %d\n", 10^-7);
    return 0;
}

Output:

2e-308 = 2e-308
2 * pow(10, -308) = 2e-308
10^-7 = -13

Note that there are a lot of gotchas with floating point numbers.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • can you give an example of the same and also a how to print that using `printf` – Aman Deep Gautam Jun 20 '12 at 07:29
  • The statement I used in my program was `falsePositivity = 0.0000001` which when printed with `printf("%lf\n", false_positivity)` gives `0.000000` as answer. – Aman Deep Gautam Jun 20 '12 at 07:30
  • 1
    The problem is with `%lf`. There are two parts of `%lf` that are wrong. First, `l` does not belong there (it is for integers). Second, `f` only prints out seven digits by default. You either want `%g` for arbitrarily small numbers, so it will switch to scientific notation, or you want `%.10f` (or some other number) to increase the precision of `%f`. You can also use `%e`, which always uses scientific notation. – Dietrich Epp Jun 20 '12 at 07:35
3

Try GNU MPFR library and GNU GMP library

The MPFR library is a C library for multiple-precision floating-point computations with correct rounding.

GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface.

AurA
  • 12,135
  • 7
  • 46
  • 63
1

Is long double sufficient? Some implementations use 128bit long double, which should easily handle your requirements.

http://en.wikipedia.org/wiki/Quadruple_precision

If you're looking for something extremely strong, check out MPFR

  • In the Wikipedia article, it also mentioned that there is no guarantee that you can get quadruple precision with `long double` keyword. – nhahtdh Jun 20 '12 at 07:36