Simple Maths?

Hi , Can someone explain please:

d = round(kts*2); //to round to the nearest 1/2kt, multiply by 2, then round

ktsr=d/2; //then divide by 2

//ktsr = ((round(kts*2))/2); //why doesn't this work in place of the two lines above?

Thanks.

Are d, kts, ktsr all double or float types?

all double

round() does what you want, all by itself. Doesn't it?
"The round() function rounds __x to the nearest integer, but rounds halfway cases away from zero (instead of to the nearest even integer). Overflow is impossible."

I'm rounding to the nearest 0.5, the top two lines do this, the third one doesn't ....

round(x+0.5)-0.5 ?

round(10.1+0.5) = 11 - 0.5 = 10.5?

so no ....

soaringpaul:
round(10.1+0.5) = 11 - 0.5 = 10.5?

so no ....

Really? I think 10.1 rounded to the nearest 0.5 is 10.5. What is your definition of rounding?

the third one doesn't

What DOES it do?

Note that it is utterly impossible for us to repeat whatever it is that you did, because you left out so many essential details. For hints on how to use this forum, please read the "How to use this forum" post.

On some platforms, including some versions of Arduino, round() returns a long integer. See round() macro in Arduino.h · Issue #76 · arduino/ArduinoCore-API · GitHub

Yes, please post a complete test sketch to demonstrate the problem, so it can be duplicated locally.

aarg:
Really? I think 10.1 rounded to the nearest 0.5 is 10.5. What is your definition of rounding?

Wouldn't 10.1 rounded to the nearest .5 be 10.0 ?
I would think anything from 9.75 to 10.24 would round to 10.0, 10.25 to 10.74 would round to 10.5.

(edit)
I think your problem is that the math is being done as integer math in the 2nd method. If round() returns an integer, then the division by 2 is done with integer math, and loses the fractional part before being stored as a double. In the first method, the integer returned by round is stored as a double, then the following statement is dividing a double by 2, causing the math to be done in floating point.

Change the divisor to 2.0 and it will work.

ktsr = ((round(kts*2))/2.0);

david_2018:
If round() returns an integer

But it doesn't in avr gcc...

aarg:
But it doesn't in avr gcc...

Unfortunately, in Arduino.h it is defined as a macro returning a long

#define round(x)     ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

If you remove the define, the compiler will use round() from math.h which does return a floating point number.

#undef round

See this discussion:
round() macro in Arduino.h

I risk stating my opinion of that. :slight_smile:

Others have been less reticent. See link in reply #8.

Problem solved.

Thank you,
David_2018. Diviser 2.0 does work.
I didn't understand why the round works differently in each method but why worry?
As you can gather, I'm completely out of my depth here!
Paul H