Hello Community! First time poster here :)
I am debugging some code and am completely perplexed by a comparison between and integer and a float that sometimes evaluates true.
In the following code, a floating-point calculation is performed, typecast to a unsigned integer, which is then compared to another float. I expect that in all but the zero case, this evaluation would fail. And usually it does. But sometimes it evaluates true, and I am trying to understand what conditions lead to this.
float gA = 0.00356270161773046;
float gB = 0.00336178532868241;
[...]
float sA = 0.5 / gA;
float sB = 0.5 / gB;
const float PA = sA * gA;
if(sB == (uint16_t)(PA / gB)) // Evaluates true.
if(sB == (uint16_t)(PA / gB))
// Evaluates true.
In the above code, gA and gB are similar but different values, set elsewhere in the snipped portion, and by varying them slightly I can change the result of the evaluation. For example:
if gB = 0.00336178532868241 -> TRUE
if gB = 0.00332519446796205 -> FALSE
But I don't understand why it is ever evaluating true..!
This code was written by someone else - who is much more experienced than me - and I have little idea what they are trying to achieve through this typecast to uint16_t. Can anyone recognise what is being done here? Does this cast operation have the same (converting/rounding) function as it does in gcc etc, or is it a true typecast?
uint16_t
This code is compiled via C51 for a C8051 microcontroller application, in case that is relevant. I cannot debug or rebuild the code.
Thank you!
Interesting. The cast to uint16_t should round positive numbers toward zero; negative values will become zero. I would guess that the original author was looking for cases where sB and (uint16_t)(PA/gB) had the same number of significant bits, but didn't want to use floor().
Adam Lins said: negative values will become zero.
Only if they're larger than -1.0 All other cases cause undefined behavioiur. As in: boom, your code just exploded.
Adam Lins said:looking for cases where sB and (uint16_t)(PA/gB) had the same number of significant bits
That doesn't even come close to what that code actually does, so let's hope that wasn't what it was meant to do.
Thanks for the thought - yes, that was my first interpretation too. If the author had cast both to uint16_t first, then it would be clear enough - if perhaps a little hacky. Indeed, I believe from the larger code operation that this to be the author's functional intention; to check if the s* values are nearly the same, and I would not expect any negative values in this context. I haven't ruled out that this is actually just an error that wasn't caught along the way; the author is pretty good, though, so I always assume they get it right and I just am mis-understanding (until proven otherwise :p)
Broeker, you are being quite aggressive with your response here. Adam is trying to help us understand what this code is doing by proposing a explanation, not saying how it should be done in an ideal, generalised way. I think you also full well know what Adam was trying to say in his explanation.