Log calls return NaN in C [duplicate] - c

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 6 years ago.
I have an array of double:
double theoretical_distribution[] = {1/21, 2/21, 3/21, 4/21, 5/21, 6/21};
And I am trying to computer it's entropy as:
double entropy = 0;
for (int i = 0; i < sizeof(theoretical_distribution)/sizeof(*theoretical_distribution); i++) {
entropy -= (theoretical_distribution[i] * (log10(theoretical_distribution[i])/log10(arity)));
}
However I am getting NaN, I have checked the part
(theoretical_distribution[i] * (log10(theoretical_distribution[i])/log10(arity)))
And found it to return NaN itself, so I assume it's the culprit, however all it's supposed to be is a simple base conversion of the log? Am I missing some detail about the maths of it?
Why is it evaluating to NaN.

You are passing 0 to the log10 function.
This is because your array theoretical_distribution is being populated with constant values that result from integer computations, all of which have a denominator larger than the numerator.
You probably intended floating computations, so make at least one of the numerator or denominator a floating constant.

Related

C: is there anyway i can get the modulo operator to work on non integer values? [duplicate]

This question already has answers here:
How to use % operator for float values in c
(6 answers)
Floating Point Modulo Operation
(4 answers)
Closed 2 years ago.
I need to reset the value of a variable called theta back to 0 everytime its value reaches or exceeds 2 PI. I was thinking something along the lines of:
int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++)
theta = (theta + inc) % 2*PI;
Of course it wont work because % doesn't work on floating points in C. Is there another equivalent or better way to achieve what I'm trying to do here? All replies are welcome. Thanks
Use the standard fmod function. See https://en.cppreference.com/w/c/numeric/math/fmod or 7.2.10 in the C17 standard.
The fmod functions return the value x − n y , for some integer n such that, if y is nonzero, the result
has the same sign as x and magnitude less than the magnitude of y.
So theta = fmod(theta, 2*PI) should be what you want, if I understand your question correctly.
If it really must be done on float instead of double, you can use fmodf instead.
Since division is really just repeated subtraction, you can get the remainder by checking if the value is at least 2*PI, and if so subtract that value.
int n = 10;
float inc = 2*PI/n;
for(int i=0;i<10;i++) {
theta += inc;
if (theta >= 2*PI) theta -= 2*PI;
}
Note that because the amount of the increment is less than the 2*PI limit we can do the "over" check just once. This is likely cheaper than the operations that would be involved if fmod was called. If it was more you would at least need while instead, or just use fmod.

What is wrong with this expression on the code? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
I have written this piece of code in my computer and the result is 7 instead of 8 (the correct result ... I think).
I don't know why... Can somebody help me?
#include <stdio.h>
int main() {
int num;
num = (68/10.0 - 68/10)*10;
printf("the result %d", num);
return 0;
}
double typically represents exactly about 264 different numbers. 68/10.0 is not one of them,
As a binary64, 68/10.0 is about
6.7999999999999998223643161..., the closest value to 6.8 that is a multiple of a dyadic rational. # AntonH
68/10 is an integer division with a quotient of 6.
(68/10.0 - 68/10)*10 is thus about 7.9999999999999982236431606...
Assigning that to an int is 7 not 8 as the fraction is discarded even though it is very close to 8.
When converting a floating point value consider round to the the closest, rather than truncating.
num = lround((68/10.0 - 68/10)*10);

pow() function giving wrong answer [duplicate]

This question already has an answer here:
pow() function in C problems [duplicate]
(1 answer)
Closed 3 years ago.
I'm trying to multiply 2, 3 digit numbers.
I used 2 for loops (nested) and multiplied each digit of num1 with num2,
and shifted each result to the appropriate place using pow().
So the problem is pow(10,3) is coming out to be 299 instead of 300.
I haven't tried much as but used printf to find what is actually happening in the runtime and this is what I have found.
the values of tempR after shift should be
5,40,300,100,800,6000,1500,12000,90000
but are coming as
5,40,299,100,799,6000,1500,12000,89999
int main(void)
{
int result; // final result
int tempR; // temporary for each iteration
char a[] = "345"; // number 1
char b[] = "321"; // number 2
for(int i = 2;i>= 0 ; i --)
{
for(int j = 2;j >= 0 ; j --)
{
int shift = abs(i-2 + j -2);
printf("%d\n",shift); //used to see the values of shift.
//and it is coming as expected
tempR = (int)(b[i] - '0') * (int)(a[j] - '0');
printf("%d \n",tempR); // value to tempR is perfect
tempR = tempR*pow(10,shift);
printf("%d \n",tempR); // here the problem starts
result += tempR;
}
}
printf("%d",result);
}
Although IEEE754 (ubiquitous on desktop systems) is required to return the best possible floating point value for certain operators such as addition, multiplication, division, and subtraction, and certain functions such as sqrt, this does not apply to pow.
pow(x, y) can and often is implemented as exp(y * ln (x)). Hopefully you can see that this can cause result to "go off" spectacularly when pow is used with seemingly trivial integral arguments and the result truncated to int.
There are C implementations out there that have more accurate implementations of pow than the one you have, particularly for integral arguments. If such accuracy is required, then you could move your toolset to such an implementation. Borrowing an implementation of pow from a respected mathematics library is also an option, else roll your own. Using round is also a technique, if a little kludgy if you get my meaning.
Never use float functions for the integer calculations. Your pow result almost never will be precise. In this case it is slightly below 300 and the cast to integer makes it 299.
The pow function operates on doubles. Doubles use finite precision. Conversion back to integer chops rather than rounding.
Finite precision is like representing 1/3 as 0.333333. If you do 9 * 1/3 and chop to an integer, you'll get 2 instead of 3 because 9 * 1/3 will give 2.999997 which chops to two.
This same kind of rounding and chopping is causing you to be off by one. You could also round by adding 0.5 before chopping to an integer, but I wouldn't suggest it.
Don't pass integers through doubles and back if you expect exact answers.
Others have mentioned that pow does not yield exact results, and if you convert the result to an integer there's a high risk of loss of precision. Especially since if you assign a float type to an integer type, the result get truncated rather than rounded. Read more here: Is floating math broken?
The most convenient solution is to write your own integer variant of pow. It can look like this:
int int_pow(int num, int e)
{
int ret = 1;
while(e-- > 0)
ret *= num;
return ret;
}
Note that it will not work if e is negative or if both num and e is 0. It also have no protection for overflow. It just shows the idea.
In your particular case, you could write a very specialized variant based on 10:
unsigned int pow10(unsigned int e)
{
unsigned int ret = 1;
while(e-- > 0)
ret *= 10;
return ret;
}

Representing floating point numbers in c [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
I have read that floating numbers are stored as per IEEE 754 representation and sometimes approximate value is displayed if its not possible to represent the number.
I have written the following code in which i am extracting fractional part then multiplying it by 10 nine times inside the loop. At the end of the loop the value is 142000000.000000 (variable g).
I multiplied it again with 10 outside the loop and got the result as 1419999999.999999.
I stored the value which was calculated inside for loop explicitly in another variable(k) and multiplied it with 10 and got the result as 1420000000.000000
Can you please tell me why the difference how it is able to store the value correctly in the second instance (In variable k).
#include<stdio.h>
#include<math.h>
int main()
{
double f=3.142,g,i;
int j;
g=modf(f,&i);
printf("Inside loop");
for(j=1;j<=9;j++)
{
g = g * 10.0;
printf("\n%lf",g);
}
printf("\nLoop ends");
g = g * 10.0;
printf("\nThe value of g is %lf",g);
double k = 142000000.000000;
k = k * 10.0;
printf("\nThe value of k is %lf",k);
}
Output
Inside loop
1.420000
14.200000
142.000000
1420.000000
14200.000000
142000.000000
1420000.000000
14200000.000000
142000000.000000
Loop ends
The value of g is 1419999999.999999
The value of k is 1420000000.000000
The initial value of f is 3.142. This value can't be represented exactly, so any operations on this value will also result in an inexact value. That's why you eventually end up printing an inexact value.
In contrast, the initial value of k is 142000000.000000 which can be represented exactly as a double. Multiplying this value by 10 still gives a value that can be represented exactly.

Labwindows strange behavior when adding DOUBLE numbers [duplicate]

This question already has answers here:
Floating point comparison revisited
(4 answers)
Closed 8 years ago.
I am running the following block of code inside a CALLBACK function for a timer.
if (start_value <= end_value)
{
start_value += increment_value;
}
else
{
return 0;
}
all three variables are defined as DOUBLE.
Double start_value = 26.0;
Double end_value = 28.0;
increment_value = 0.1;
when adding the increment_value to start_value, the value of the variable start_value does not simply reflect the expected result of the addition. For example, when start_value is 26.0, after one addition, the value of start_value is 26.10000000001. The trailing 1 causes problems later on in the code, because when the expected result of the comparison is expected to be TRUE, it is evaluated as false because of the trailing 1.
Why is this happening?
Eshan, The == operator is looking for an exact match, and should be used exclusively for integer comparisons (where exact is possible). So, "why is this happening?" because 26.10000000001 is not equal to 26.1. The difference between the two is sometimes referred to as floating point error.
As long as we are using binary storage of floating point, there will continue to be floating point error. This requires that methods to compare floating points have to be different than when comparing integers. (i.e. for floats, cannot use (x == y) ?. A quick and dirty alternative to "==" when comparing floats is to do something like this: if(abs(x-y)<epsilon ){//equal} where epsilon is some small tolerance value like 0.000001
So, try something like this instead:
int main(void)
{
double start_value = 26.0;
double end_value = 28.0;
double increment_value = 0.1;
#define EPSILON 0.000001
while(fabs(start_value-end_value)>EPSILON )
{
printf("not equal\n");
start_value += increment_value;
}
printf("equal\n");
getchar();
}
Note: choose epsilon value to match the neighborhood of significant digits in the comparisons you will do.
There are many other good methods, (and many who will say this is not one of them) but I have used this one for years, and for my purposes, it has worked well.
HERE is a link talking a little about this, and other methods.

Resources