Phrogz
Phrogz

Reputation: 303244

Round to nearest odd digit

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

Answers (3)

Avik Paul
Avik Paul

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

Oliver
Oliver

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

Phrogz
Phrogz

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

Related Questions