Reputation: 303244
I want to round some numbers to the nearest tenth, using odd tenths only. e.g.
91.15 -> 91.1
91.21 -> 91.3
What's a simple and generic equation for doing this?
Upvotes: 4
Views: 4142
Reputation: 76
First let's answer the question how to find the nest odd integer, fast and efficient without branch and compare. Then that formula can be extended to the above question by first multiplying by a power of 10 before the transformation and then diving (converting back to float again) by the same power of 10, e.g. 10 for nearest odd tenth, 100 for the nearest odd hundredth, and so on.
If you are using languages like Java or C++ with truncated divide and bit-shift operator support, use this one line formula :
// Java : with bit-shift
static int nearestOdd(float num) {
return 1 + (((int)(num + 1.0f) - 1) & 0xFFFFFFFE);
}
// Java : without bit-shift.
static int nearestOdd(float num) {
return 1 + 2 * (((int)(num + 1.0f) - 1) / 2);
}
In C++ :
// C++
int nearestOdd(float num) {
return 1 + ((static_cast<int>(num + 1.0f) - 1) & 0xFFFFFFFE);
}
Upvotes: 0
Reputation: 29493
How about
function roundToOdd(number)
temp = math.floor(number * 10 + 0.5)
if temp % 2 == 0 then
-- first decimal is even, need to decide whether to "round" up or down
if number > temp/10 then
-- closer to the next odd digit "up"
temp = temp + 1
else
-- closer to the next odd digit "down"
temp = temp - 1
end
end
return temp/10
end
for n=1, 2, 0.09 do
local result = roundToOdd(n, 0.2, 0.1)
print(string.format("%.2f : %g", n, result))
end
print(91.15,roundToOdd(91.15))
print(91.21,roundToOdd(91.21))
Results:
1.00 : 0.9
1.09 : 1.1
1.18 : 1.1
1.27 : 1.3
1.36 : 1.3
1.45 : 1.5
1.54 : 1.5
1.63 : 1.7
1.72 : 1.7
1.81 : 1.9
1.90 : 1.9
1.99 : 1.9
91.15 91.1
91.21 91.3
Upvotes: 4
Reputation: 303244
This is not rounding to the nearest tenth, but rather rounding to the nearest fifth (two-tenth) with a one-tenth offset. With that in mind, the general equation is:
# Any language where 'round' rounds to the nearest integer
radioStation = round( (original-offset)/interval ) * interval + offset
In Lua:
-- number: the original value to round
-- interval: the distance between desired values
-- offset: an optional shifting of the values
function roundToNearest( number, interval, offset )
offset = offset or 0 -- default value
interval = interval or 1 -- default value
return math.floor( (number-offset)/interval + 0.5 ) * interval + offset
end
for n=1, 2, 0.09 do
local result = roundToNearest(n, 0.2, 0.1)
print(string.format("%.2f : %g", n, result))
end
--> 1.00 : 1.1
--> 1.09 : 1.1
--> 1.18 : 1.1
--> 1.27 : 1.3
--> 1.36 : 1.3
--> 1.45 : 1.5
--> 1.54 : 1.5
--> 1.63 : 1.7
--> 1.72 : 1.7
--> 1.81 : 1.9
--> 1.90 : 1.9
--> 1.99 : 1.9
Upvotes: 8