-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix arithmetics overflow warnings with VS2019 #1877
base: master
Are you sure you want to change the base?
Conversation
@@ -116,7 +116,7 @@ float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len) | |||
for (i = 0; i < len; i++) { | |||
int32_t x = iq_buf[2 * i]; | |||
int32_t y = iq_buf[2 * i + 1]; | |||
y_buf[i] = (int)sqrt(x * x + y * y) >> 1; // max 46341, scaled 23170, fs 16384 | |||
y_buf[i] = (int)sqrt((double)x * x + (double)y * y) >> 1; // max 46341, scaled 23170, fs 16384 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is fixed point by design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but sqrt
takes a double
which is why there is the warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that sqrtf() should work and is slightly better type wise. If it is better accuracy wise I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the point is that x and y are limited to [-128,127] because of iq_buf being bytes, but the compiler is not figuring it out? Is there in fact an overflow possibility, as determined by a human reviewing? Or is it a false positive warning. The position I have seen elsewhere, and tend to agree with, is that code should be fixed for valid warnings, and not modified much if any for invalid warnings, except that restructuring it slightly to be easier to reason about, withtout hurting the generated code is ok.
@@ -85,7 +85,7 @@ float magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len) | |||
for (i = 0; i < len; i++) { | |||
int16_t x = iq_buf[2 * i] - 128; | |||
int16_t y = iq_buf[2 * i + 1] - 128; | |||
y_buf[i] = (uint16_t)(sqrt(x * x + y * y) * 128.0); // max 181, scaled 23170, fs 16384 | |||
y_buf[i] = (uint16_t)(sqrt((double)x * x + (double)y * y) * 128.0); // max 181, scaled 23170, fs 16384 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fixed point but I guess there is a reason for the 128.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the reason is more about sqrt
taking a double
instead of a float
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a test function, still turning int muls into double muls isn't great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And same here with sqrtf().
src/pulse_analyzer.c
Outdated
device.gap_limit = to_us * (hist_gaps.bins[1].max + 1); // Set limit above next lower gap | ||
device.reset_limit = to_us * (hist_gaps.bins[hist_gaps.bins_count - 1].max + 1); // Set limit above biggest gap | ||
device.gap_limit = to_us * (hist_gaps.bins[1].max + 1.0); // Set limit above next lower gap | ||
device.reset_limit = to_us * (hist_gaps.bins[hist_gaps.bins_count - 1].max + 1.0); // Set limit above biggest gap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not great, it was int addition before, now it's double addition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, yes, the warning is about doing a 4 byte addition that then gets promoted to an 8 byte type for the multiplication, potentially leading to an overflow.
Using the floating point constant forces double
computation which is not great, I agree. But how do I get rid of the warning then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is non performance critical code. I'm fine with this change here but maybe it should be a cast? gap_limit is (float) while to_us is (double).
8e31ece
to
e42ad33
Compare
4e3d436
to
3eb7966
Compare
I have just rebased this branch on the latest master, please let me know if this is still of interest |
Yes, these clean-ups are of interest. I really need to find quiet time to contemplate the effects (e.g. changing some double calcs to float only). |
3eb7966
to
16d39f2
Compare
93031a1
to
ed794ec
Compare
…at and not on int16_t that could overflow
16d39f2
to
1285116
Compare
@@ -126,7 +126,7 @@ float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len) | |||
|
|||
// Fixed-point arithmetic on Q0.15 | |||
#define F_SCALE 15 | |||
#define S_CONST (1 << F_SCALE) | |||
#define S_CONST ((int)(1 << F_SCALE)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This surprises me. What type is 1<< F_SCALE without a cast. unsigned int?
This fixes warnings of this kind, seen via #1866: