Given two inputs, x and y, round x to one less significant figure, then repeat until it has y number of unrounded digits left. (the decimal point does not count as a digit)

Input & Output

Input can be a combination of strings and integers, e.g. you can have the input as a string and the output as an int, or vice versa.
The input number will never have 15 digits total, and the y will never be greater than the input number's length and will always be greater than 0.

x = 32.64712, y = 3
    32.64712 -> 32.6471 -> 32.647 -> 32.65 -> 32.7  (Three unrounded digits left)

x = 87525, y = 2
    87525 -> 87530 -> 87500 -> 88000 (Two unrounded digits left)

x = 454, y = 3
    454 -> 454 (Three unrounded digits left)

(steps shown just to clarify, you only need to output the last value.)


  • Trailing 0's are allowed
  • 5's round up
  • Standard loopholes apply

This is , so you should strive for the shortest answer.

  • 1
    \$\begingroup\$ I take it numbers ending in 5 round up? If we get a result like 3.100, do we have to output the number with trailing zeroes? \$\endgroup\$ – xnor Dec 12 '18 at 4:53
  • 3
    \$\begingroup\$ The phrase "round x's second to last digit" seems ambiguous and I'd interpret it differently from what the challenge intends. I'd call it "round away x's last digit" or "round x to one less significant figure". Also, the input refers to integers, but the numbers can be non-whole reals. \$\endgroup\$ – xnor Dec 12 '18 at 5:00
  • \$\begingroup\$ @xnor Numbers ending in 5 do round up, trailing zeros are ok \$\endgroup\$ – Embodiment of Ignorance Dec 12 '18 at 5:10
  • \$\begingroup\$ Ugh, JavaScript rounds 32.647 to 32.64999999999999857891 which is still less than 32.65 ;-( \$\endgroup\$ – Neil Dec 12 '18 at 9:47
  • \$\begingroup\$ For javascript, you can scale the number up so that there are no digits right of the decimal point, then divide it down after scaling(since integer math is exact) \$\endgroup\$ – Embodiment of Ignorance Dec 12 '18 at 18:19

Python 2, 101 97 92 91 85 bytes

lambda x,y:reduce((lambda n,l:int(n/.1**l+.5)*.1**l),range(15,y+~len(`int(x)`),-1),x)

Try it online!

Alternative : If Python's round would round "half up" instead of "half to even":

Python 2, 57 bytes

lambda x,y:reduce(round,range(15,y-len(`int(x)`)-1,-1),x)

Try it online!


Perl 6, 59 bytes

{($^a,{.round(10**($++-15))}...^0|any 10 X**^30-15)[*-$^b]}

Try it online!

Anonymous code block that takes two numbers and returns a number.


{                                                         }  # Anonymous code block
 (                          ...                   )  # Create a sequence
  $^a,   # With the first element as the input
      {                    }  # With each element being
       .round(10**($++-15))   # The previous element rounded by another digit
                                0                   # Until 0
                                 |                  # or
                                  any 10 X**^30-15  # Any available power of 10
                               ^  # Ignoring the last number
                                                   [*-   ]  # Index from the end
                                                      $^b   # The second number

JavaScript (ES6), 58 bytes

<div oninput=o.textContent=f(+x.value,+n.value)><input id=x><input id=n type=number min=1 max=15 value=3><pre id=o>

Arithmetic solution. The given procedure rounds numbers up if they are greater than 4/9 of the next value, so if rounding doesn't increase the number, try again with a slightly greater value.


R, 79 bytes

Unfortunately, R uses "round to even" when rounding off a .5

function(x,y){for(i in nchar(gsub('\\.','',x)):y){x=signif((x*100+1)/100,i)};x}

Try it online!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.