Double equals in C

WBahn

Joined Mar 31, 2012
32,993
When testing for limits, you should not test for equality. Use <= and >= instead of ==.
If you are using float or real data types, never use ==.
It's more subtle than that. Many programmers think that just using <= instead of == solves the problems associated with floating point comparisons. It doesn't. What I always recommend, and I diligently try to follow my own advice, is that any time you are performing relational operation on floating point values, you need to carefully consider the implications of near-equality. What should happen, or at least what is acceptable, if the comparison barely misses equality on either side. If the answer isn't that both outcomes are tolerable, then you have quite a bit more work to do, and usually the best solution is to refactor the logic so that you are making decisions based on well-crafted integer expressions.

As a couple of examples, if you are testing whether a temperature has exceeded a particular threshold, it almost certainly doesn't matter if you call it too high when it is barely under the threshold or call it within limits if it is barely out of limits. What the correct decision is were it to be exactly at the bound is a coin-flip. A bit of noise in the system could result in the technically wrong decision being made, but it doesn't matter. So this is a place where using > or >= are equally appropriate and doing a floating point inequality for the test is perfectly reasonable. Use whichever operator makes the most sense from a readability standpoint.

But let's say that you want to take measurements at values (perhaps voltage values) from 2.0 to 4.0, inclusive, in increments of 0.2. A common first-shot at the logic might be:

Code:
double v = 2.0;
while (v <= 4.0)
{
   y = measure(v);
   v += 0.2;
}

The fact that we are not checking for exact equality is sufficient to satisfy many programmers that life is good, but the real question that needs to be considered is what should happen if, due to accumulated roundoff error, a value of v is reached that is slightly less than 4.0 versus slight greater than 4.0? The final intended measurement may or may not get made.

This is NOT a C issue, this is a general logic issue when dealing with floating point computations. In this case, it's better to recraft the code so that it based on taking n data samples and computing the voltage value for each based on an integer counter.
 

MrChips

Joined Oct 2, 2009
34,968
That's awesome!

When you get a chance, will you post code to perform a polynomial regression against a 2nd order equation for arbitrary input data using integer math?

Thanks.
I did dewpoint calculation from temperature and humidity to 0.1 degree resolution in both °C and °F, all in integer arithmetic. Does that count?
 

nsaspook

Joined Aug 27, 2009
16,373
Another one of my peeves is the reluctance to use FP when it simplifies and makes X application software easier. This is double true when people are using 32-bit controller hardware with IEEE 754 FP hardware that's faster than integer math.

I don't have my own FP lib but I still use the generic C FP even on 8-bit controllers for complex calculations when I know the result will be used elsewhere externally (networking) as reals/floats.
The trick is FP task isolation and wise hardware utilization of interrupts, DMA and other hardware features to make the calculations independent of resource speed/time hungry tasks when you only have software FP.
 

Attachments

joeyd999

Joined Jun 6, 2011
6,361
We understand the power and convenience of FP math.
We also know that FP math occupies more MCU time and space.
We also know the pitfalls of relying on FP math when proper care is not applied.

https://wiki.sei.cmu.edu/confluence/display/c/FLP00-C.+Understand+the+limitations+of+floating-point+numbers#:~:text=As a result, they do,about either precision or range.
What's your reply got to do with 2nd Order Polynomial Regression Over Arbitrary Data Sets except that it's nearly impossible to do with integer arithmetic?

And who is "we"? Someone sitting next to you?
 

nsaspook

Joined Aug 27, 2009
16,373
We understand the power and convenience of FP math.
We also know that FP math occupies more MCU time and space.
We also know the pitfalls of relying on FP math when proper care is not applied.

https://wiki.sei.cmu.edu/confluence/display/c/FLP00-C.+Understand+the+limitations+of+floating-point+numbers#:~:text=As a result, they do,about either precision or range.
This is the one that might not be true today with 32-bit controllers. So , no, we don't know that automatically as a fact.
Even the latest versions of the ESP32 have (typically bad) single precision FP hardware that's as fast as integer for most MOPS testes.
The cheapest available MCU with a floating point unit also has Wi-Fi and Bluetooth built in.
 
Last edited:

sobi shah

Joined Apr 13, 2024
1
I was just wondering what benefits the == test for equality bring to the C language over the single = that other languages (Basic, for instance) use.

In the C programming language, == and = serve very different purposes:

  1. == (Equality Operator):
    • == is a comparison operator used to check if two values are equal.
    • It is used in conditional statements and expressions to evaluate whether two operands are equal or not.
    • For example:
      cCopy code
      int x = 5;
      int y = 7;
      if (x == y) {
      printf("x is equal to y\n");
      } else {
      printf("x is not equal to y\n");
      }
    • In this example, == checks if the value of x is equal to the value of y.
  2. = (Assignment Operator):
    • = is an assignment operator used to assign a value to a variable.
    • It assigns the value on its right-hand side to the variable on its left-hand side.
    • For example:
      cCopy code
      int a;
      a = 10;
    • In this example, the value 10 is assigned to the variable a.
In summary, == is used for comparison, while = is used for assignment. It's essential to distinguish between these two operators to avoid logical errors in your programs
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,165
In summary, == is used for comparison, while = is used for assignment. It's essential to distinguish between these two operators to avoid logical errors in your programs
The question was why it needs to be different. There are plenty of languages that use the single equals sign for both purposes, where the compiler is perfectly capable of distinguishing from context whether the intention is assignment or comparison. Does C benefit from having two different symbols? Or does it detract from the writing of clear code? Or does it lead to errors?
I bet there were a few = where there should be == in the Fujitsu/Horizon/Post Office software scandal.
 

BobTPH

Joined Jun 5, 2013
11,576
There are plenty of languages that use the single equals sign for both purposes
In C:

a = b;

and

a == b;

Are both valid syntax with different meanings. You may say the second statement is extraneous, but if either a or b is a volatile hardware register, it will have consequences.

It gets worse:

In the middle of an expression,

(a = b)

and

(a==b)

Are also both valid with different meanings.

So no, they are not different because it is “easier to parse”, they are different so it is possible to parse. Without the difference, C becomes ambiguous.
 

ApacheKid

Joined Jan 12, 2015
1,762
Using = for assignment was a poor decision really, right there is where stuff started go down the wrong path.

A statement like

a = a + 1

is nonsensical, mathematically false.
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,165
Using = for assignment was a poor decision really, right there is where stuff started go down the wrong path.

A statement like

a = a + 1

is nonsensical, mathematically false.
but
a=b+1
makes sense.
In mathematics it is written
\(
a_{n}=a_{n-1}+1
\)
in computer languages the subscripts are implied, because it is, in effect, a sampled system. Then it makes sense.
 

Thread Starter

Ian0

Joined Aug 7, 2020
13,165
In C:

a = b;

and

a == b;

Are both valid syntax with different meanings. You may say the second statement is extraneous, but if either a or b is a volatile hardware register, it will have consequences.

It gets worse:

In the middle of an expression,

(a = b)

and

(a==b)

Are also both valid with different meanings.

So no, they are not different because it is “easier to parse”, they are different so it is possible to parse. Without the difference, C becomes ambiguous.
I can't think of an application in C where using = deliberately in an if statement is in any way consistent with writing clear and easy-to-follow software.
 
Top