Calculations between VERY small numbers.

I am doing a class assignment on calculating very small numbers. I didn't get very far because the numbers all somehow turn into 0. Like 1/13! is a very small decimal number, but my program outputs '0' instead. So I can't really do any calculation at all.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using namespace std;

long long factorial(int);
double calculate(double[]);

int main(){

    double coef[] = {
        2/factorial(14)
        -1/factorial(13),
        -1/factorial(11),
        2/factorial(10),
        -1/factorial(9),
        -1/factorial(7),
        2/factorial(6),
        -1/factorial(5),
        -1/factorial(3),
        1,
        -1
    };
    //This array holds very small coefficients of 11 variables of a function.

    printf("Number is: %.15f\n", calculate(coef));
    //This prints 0.000000000000000, which is not what my TI-84 calculator shows me.
}

//I want to pass this array to this function 'calculate' and do some simple arithmetic.
double calculate(double coef[]){
    
    //The below line calculates 2/14! - -1/13!, which is a very small number.
    double number = coef[0] - coef[1];
    return number;
}

//A function to calculate factorials.
long long factorial(int number){
    return( number == 1 ) ? 1: number * factorial( number-1 );
}
What a bizarre username!

Anyway, you are suffering from the truncation resulting from integer division. e.g.2/3 would give 0.

Even the subsequent assignment to a double doesn't solve the problem. However, writing 2.0/ rather than 2/ etc. would, as the integer would be promoted to a double before doing the calculation.

Also, note that factorials have a tendency to outgrow integer types pretty quickly. There are more reliable methods of calculating the reciprocals of factorials.
Last edited on
in C++, the operation ( int / long long ) gives you an int.

So

2 / (factorial(14)

gives you zero.

2/14! - -1/13! is the same as zero + zero, which is zero.


See it yourself with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using namespace std;

#include <cstdio>
#include <iostream>

long long factorial(int);
double calculate(double[]);

int main(){

  std:: cout << "factorial(14) = " <<  factorial(14) << '\n';
  
  std:: cout << "2 / factorial(14) = " << 2 / factorial(14) << '\n';
  
    double coef[] = {
        2/factorial(14)
        -1/factorial(13),
        -1/factorial(11),
        2/factorial(10),
        -1/factorial(9),
        -1/factorial(7),
        2/factorial(6),
        -1/factorial(5),
        -1/factorial(3),
        1,
        -1
    };
    //This array holds very small coefficients of 11 variables of a function.

    printf("Number is: %.15f\n", calculate(coef));
    //This prints 0.000000000000000, which is not what my TI-84 calculator shows me.
}

//I want to pass this array to this function 'calculate' and do some simple arithmetic.
double calculate(double coef[]){
    
    //The below line calculates 2/14! - -1/13!, which is a very small number.
    double number = coef[0] - coef[1];
    return number;
}

//A function to calculate factorials.
long long factorial(int number){
    return( number == 1 ) ? 1: number * factorial( number-1 );
}


and then stop doing ( int / int ) if you need a non-integer answer.

Try this instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <cstdio>

long long factorial(int);
double calculate(double[]);

int main(){
  
    double coef[] = {
        2.0/factorial(14)
        -1.0/factorial(13),
        -1.0/factorial(11),
        2.0/factorial(10),
        -1.0/factorial(9),
        -1.0/factorial(7),
        2.0/factorial(6),
        -1.0/factorial(5),
        -1.0/factorial(3),
        1.0,
        -1.0
    };
    //This array holds very small coefficients of 11 variables of a function.

    printf("Number is: %.15f\n", calculate(coef));
    //This prints 0.000000000000000, which is not what my TI-84 calculator shows me.
}

//I want to pass this array to this function 'calculate' and do some simple arithmetic.
double calculate(double coef[]){
    
    //The below line calculates 2/14! - -1/13!, which is a very small number.
    double number = coef[0] - coef[1];
    return number;
}

//A function to calculate factorials.
long long factorial(int number){
    return( number == 1 ) ? 1: number * factorial( number-1 );
}


This still won't give you the answer you're expecting, though...


THEN, realise that floating point numbers do not work like they do inside your head, but instead they have to work the brutal limits of how they are constructed: https://floating-point-gui.de/



Last edited on
windows 10 calc stinks but you can get the constants from it to more digits than a standard double (64 bit) will hold.
if you have access to extended doubles, 80+ bit, use them. Depends on your hardware FPU.
everything you have is just a constant...
Last edited on
Thank you guys for the quick reply. I have changed my array to what you have suggested and I am so glad the solution was so simple! However, I did encounter more problem..

I noticed that

 
cout << "2.0/factorial(14) - -1.0/factorial(13) = " << 2.0/factorial(14) - -1.0/factorial(13)<< '\n';


outputs enough precision that I can actually use in my calculation. However, this

 
cout << "coef[0] - coef[1] = " << coef[0] - coef[1]<< '\n';


does not. Is it because it's a calculation between two double datatype? Why does "2.0/factorial(14) - -1.0/factorial(13)" give me the correct number, while the former does not?

Edit: I actually noticed that the numbers in the array coef, is not entirely correct when I print them to the console.

Second edit: WOW. I forgot a COMA in the first element of the array and that was messing up my entire calculation!! Please ignore this entire embarrassing comment.
Last edited on
To add to that embarrassment I think you meant COMMA, but don't sweat, I'm told PMS is a worse type of suffering.
Topic archived. No new replies allowed.