I need to convert and round F to C. My function is simply:
return (int)((((float)5 / (float)9) * (f - 32)) + 0.5)
But if I input 14 f, I get back -9 c, instead of -10 c.
I need to convert and round F to C. My function is simply:
return (int)((((float)5 / (float)9) * (f - 32)) + 0.5)
But if I input 14 f, I get back -9 c, instead of -10 c.
C has a nice function lround()
to round and convert to an integer.
The lround and llround functions round their argument to the nearest integer value, rounding halfway cases away from zero, regardless of the current rounding direction. C11dr §7.12.9.7 2
#include <math.h>
return lround(5.0/9.0 * (f - 32));
The +0.5 and than cast to int
has various troubles with it. It "rounds" incorrectly for negative values and rounds incorrectly for various edge case when x +0.5
is not exact.
Use the <math.h>
round functions, rint()
, round()
, nearbyint()
, etc) best tools in the shed.
OP comment about needing a vxWorks solution. That apparently has iround to do the job.
For a no math.h
nor double
solution:
Use (a + sign(a)*b/2)/b
idiom. After offsetting by 32 degrees F, we need c = irounded(5*f/9)
or c = irounded(10*f/18)
.
int FtoC(int f) {
f -= 32;
if (f < 0) {
return (2*5*f - 9)/(2*9);
}
return (2*5*f + 9)/(2*9);
}
((14 - 32) * 5.0) / 9.0 = -10.0
-10.0 + 0.5 = -9.5
(int)(-9.5) = -9
Adding 0.5
for rounding purposes will only work when the result of the calculation of f - 32
is positive. If the result is negative, it has to be changed to -0.5
.
You could change your code to this:
int roundVal = (f < 32) ? -0.5 : 0.5;
return (int)((((float)5 / (float)9) * (f - 32)) + roundVal);
Everyone's
"Int() doesn't function correctly in the negative region of the number line"
is completely and utterly WRONG, and quite disgusting! We programmers should know and understand the concept of "the number line"!
Int(9.5) == 10 => true
Int(-9.5) == -9 => true
Lets say we have a dataset, that coincidently is something point 5, and is a linear system. Keep in mind that this is matlab syntax, to me programming is programming, so entirely applicable in any language.
x = [-9.5:1:9.5] % -9.5 to 9.5 at increments of 1 -9.5 -8.5 -7.5 ..... 9.5
% Now we need a function Int(), and lets say it rounds to the nearest,
% as y'all say it should be: "direction of the sign". MATLAB doesn't
% have
Int()... that I know of.
function INTEGER = Int_stupid(NUMBER)
POL = NUMBER / abs(NUMBER) % Polarity multiplier
VALUE_temp = NUMBER + (POL * 0.5) % incorrectly implemented
% rounding to the nearest
% A number divided by it's absolute value is 1 times it's
% polarity
% ( -9.5 / abs( -9.5 ) ) = -1
% ( 9.5 / abs( 9.5 ) ) = 1
end
function INTEGER = Int(NUMBER) % how every other Int function works
VALUE_temp = NUMBER + 0.5 % correctly implemented rounding
% to the nearest
end
% Now we need the whole dataset rounded to the "nearest direction of the sign"
x_rounded = Int_stupid(x) => x = [-10, -9, -8,... -1, 1, 2...] % notice how there is no 0, there is % discontinuity in this bad rounding.
% Notice that in the plot there is a zig,
% or zag, in my PERFECT LINEAR SYSTEM.
% Notice the two parallel lines with no
% defects representing the RAW linear
% system, and the parallel correctly
% rounded => floor( x + 0.5 )
Rounded to the nearest data, if done correctly, will parallel the actual data.
Sorry for my anger, and programmatic insults. I expect experts to be experts, that don't sell completely incorrect information. And if I do the same, I expect the same humiliation from my peers => YOU.
References ( for 2nd grade how to round numbers ): %_https://math.stackexchange.com/questions/3448/rules-for-rounding-positive-and-negative-numbers %_https://en.wikipedia.org/wiki/IEEE_754#Rounding_algorithms
It sounds like you have two problems:
The number you're trying to round is negative, meaning that the standard trick of adding 0.5 goes the wrong way.
Standard rounding functions like round()
are for some reason denied to you.
So just write your own:
double my_round(double x, double to_nearest)
{
if(x >= 0)
return (int)(x / to_nearest + 0.5) * to_nearest;
else
return (int)(x / to_nearest - 0.5) * to_nearest;
}
Now you can write
return (int)my_round(5./9. * (f - 32), 1.0);