Labwindows strange behavior when adding DOUBLE numbers [duplicate] - c

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.

Related

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;
}

Log calls return NaN in C [duplicate]

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.

How do I determine whether the value of a float is a whole number? [duplicate]

This question already has answers here:
Checking if float is an integer
(8 answers)
Closed 8 years ago.
I have a program in which i need to print FLOAT in case of a float number or print INTEGER in case of a regular number.
for Example pseudo code
float num = 1.5;
if (num mod sizeof(int)==0)
printf ("INTEGER");
else
printf("FLOAT");
For example:
1.6 would print "FLOAT"
1.0 would print "INTEGER"
Will something like this work?
All float types have the same size, so your method won't work. You can check if a float is an integer by using ceilf
float num = 1.5;
if (ceilf(num) == num)
printf ("INTEGER");
else
printf("FLOAT");
You can use modff():
const char * foo (float num) {
float x;
modff(num, &x);
return (num == x) ? "INTEGER" : "FLOAT";
}
modff() will take a float argument, and break it into its integer and fractional parts. It stores the integer part in the second argument, and the fractional part is returned.
The "easy" way, but with a catch:
You could use roundf, like this:
float z = 1.0f;
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
The problem with this and other similar techniques (such as ceilf) is that, while they work great for whole number constants, they will fail if the number is a result of a calculation that was subject to floating-point round-off error. For example:
float z = powf(powf(3.0f, 0.05f), 20.0f);
if (roundf(z) == z) {
printf("integer\n");
} else {
printf("fraction\n");
}
Prints "fraction", even though (31/20)20 should equal 3, because the actual calculation result ended up being 2.9999992847442626953125.
So how do we deal with this?
Any similar method, be it fmodf or whatever, is subject to this. In applications that perform complex or rounding-prone calculations, usually what you want to do is define some "tolerance" value for what constitutes a "whole number" (this goes for floating-point equality comparisons in general). We often call this tolerance epsilon. For example, lets say that we'll forgive the computer for up to +/- 0.00001 rounding error. Then, if we are testing z, we can choose an epsilon of 0.00001 and do:
if (fabsf(roundf(z) - z) <= 0.00001f) {
printf("integer\n");
} else {
printf("fraction\n");
}
You don't really want to use ceilf here because e.g. ceilf(1.0000001) is 2 not 1, and ceilf(-1.99999999) is -1 not -2.
Choose a tolerance value that is appropriate for your application. For more information, check out this article on comparing floating-point numbers.
Will something like this work?
No. For example on the x86_32 and ARM 32 bit architectures sizeof(int) == 4 and sizeof(float) == 4.
Also whatever you think mod is, it clearly shows you don't understand what the sizeof operator does.

comparing double values in C

i have two double arrays, let's say A and B. i want to compare their results to 7 significant digits. will the following be correct to make the comparison?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
In order to compare doubles, you could use something like this:
bool fequal(double a, double b)
{
return fabs(a-b) < epsilon;
}
Taken from here.
fabs reference.
But make sure you understand the potential pitfalls.
No, this will not work.
The type cast operator has higher precedence than the multiplication operator. This means that A[i] and B[i] will be cast to integers (and be truncated) before being multiplied by 1e7. 2.25 and 2.5 will end up being equal to your code. You can fix that by putting the multiplication in parentheses: (int)(A[i]*k)
Also, since you're relying on truncation instead of rounding, you may end up with incorrect results (depending on what you're expecting). 1.0e-7 and 1.9e-7 will be equal (1 == 1), while 1.9e-7 and 2.1e-7 will not (1 != 2). I suggest finding a function that will round properly with the behavior you desire.
Also, your comparison does not deal with significant digits, it simply changes the value of the exponent. In the above examples, there are only 2 significant digits, however your code would only compare one of those digits because the value of the exponent is -7.
Here is some code that does what you want:
//create integer value that contains 7 significant digits of input number
int adjust_num(double num) {
double low_bound = 1e7;
double high_bound = low_bound*10;
double adjusted = num;
int is_negative = (num < 0);
if(num == 0) {
return 0;
}
if(is_negative) {
adjusted *= -1;
}
while(adjusted < low_bound) {
adjusted *= 10;
}
while(adjusted >= high_bound) {
adjusted /= 10;
}
if(is_negative) {
adjusted *= -1;
}
//define int round(double) to be a function which rounds
//correctly for your domain application.
return round(adjusted);
}
...
if(adjust_num(A[i]) == adjust_num(B[i])) {
...
}
Yes but you do have to make one change.
try (int)(A[i]*k)
to make sure that your multiplication get executed first.
Hope this helps.
When you are using two floating-point values to decide if the values they would ideally have are equal, you should have some estimate (or, better, a proven bound) of how far apart the calculated values could be if the exactly calculated values were equal. If you have such a bound, then you can perform a test like this: “If the two numbers are closer together than the error bound, then accept them as equal.” The error bound could be a single absolute number, or it could be a number relative to the magnitude of one of the values, or it could be some other function of the values.
However, there is another question you should answer. Sometimes, the above test will accept values as equal (because the two calculated values are close together, possibly even equal) even though the exactly calculated values would not be equal. So, you know whether accepting calculated values that are close to each other as equal even though the exactly calculated numbers are not equal will cause you problems. If the answer is yes, the above test will sometimes accept as equal numbers that will cause you problems, then you cannot use this test. You may have to perform your calculations a different way to reduce the errors.
Advice is often given to fabricate some seemingly small threshold and use it. This is sloppy programming and is not engineering.
As an aside, never write pow(10, 7). Write 1e7. This avoids any possibility of error in the function call and it may avoid an unnecessary functional call entirely.

Doubles that are *exactly* equal are returning 0 for (a==b) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C compiler bug (floating point arithmetic)?
I've got two doubles which I can guarantee are exactly equal to 150 decimal places - ie. the following code:
printf("***current line time is %5.150lf\n", current_line->time);
printf("***time for comparison is %5.150lf\n", (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS));
...returns:
***current line time is 39346.526736111096397507935762405395507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
***time for comparison is 39346.526736111096397507935762405395507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
FIVE_MINUTES_IN_DAYS is #defined, and current_line->time and last_stage_four_print_time are both doubles.
My problem is that the next line of my debugging code:
printf("if condition is %d\n", (current_line->time >= (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS)));
returns the following:
if condition is 0
Can anyone tell me what's going on here? I am aware of the non-decimal/inexact nature of floats and doubles but these are not subject to any error at all (the original figures have all been read with sscanf or #defined and are all specified to 10 decimal places).
EDIT: My mistake was assuming that printf-ing the doubles accurately represented them in memory, which was wrong because one value is being calculated on-the-fly. Declaring (last_stage_four_print_time + FIVE_MINUTES_IN_DAYS) as threshold_time and using that instead fixed the problem. I will make sure to use an epsilon for my comparisons - I knew that was the way to go, I was just confused as to why these values which I (incorrectly) thought looked the same were apparently inequal.
Floats certainly are not accurate to 150 significant digits, so I 'm not sure what conclusion can be drawn from the "visual" comparison (if any).
On the other hand, the values are obviously not bit-identical (and how could they be, since one of them is calculated on the spot with addition?). So it's not really clear why the behavior you see is unexpected.
Don't ever compare floats like that, just do the standard comparison of difference vs epsilon.
Read about floating point representation (particularly http://en.wikipedia.org/wiki/IEEE_754-2008). Try printing the actual contents of the bytes containing the doubles as hexadecimal and they won't match bit for bit.
The proper comparison for floats is in Knuth (Seminumerical algorithms). Simply (replace bool with int and float with double, true with 1):
bool almostEqual(float x, float y, float epsilon)
{
if (x == 0.0 && y == 0.0) {
return true;
}
if (fabs(x) > fabs(y)) {
return fabs((x - y) / x) < epsilon;
} else {
return fabs((x - y) / y) < epsilon;
}
}
You should always use an EPSILON value for comparison of floats and doubles to check for equality. Even though it looks the same the internal representation is not guaranteed to match because of the way these types of numbers are represented in binary.
You can do something like
#define EPSILON 0.00001
...
if (fabs(a - b) <= EPSILON) return 1; // they are equal
return 0;
Jesus is right about how to solve this.
As for why... in one case you read in a constant value, in the other case you perform an addition operation. Even if the printed output is exactly the same, the binary representation can be slightly different.
Try inspecting the memory backing the two double's and see if any bits are different (there will be differences).
For a comprehensive treatment, I recommend
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
In general you shouldn't use == to compare floats or doubles. You should instead check that the difference is smaller than some small number.
double second_number = last_stage_four_print_time + FIVE_MINUTES_IN_DAYS;
if (fabs(current_line->time - second_number) < 0.001 || current_line->time > second_number){
// your comparison code
}
First, doubles have just 15-16 decimal places (log_2 of 52 bit matissa).
Second, if you want to compare, use the already mentioned epsilon.
Thirdly, for debugging, print the hex value.

Resources