adaptive rounding with 9

How to round numbers up when my input varies all times ? Rounding only numbers of 9

simple examples
59 → 60

other examples
490 ->500
7090 → 7100
7900 ->8000

basically, numbers are without period ‘.’ and rounding to the next decimal or hundredth value

This is an approach performing the following steps

• Coerce the number to real.
• Declare a counter.
• Divide the real number by 10 until the remainder is not zero and increment the counter
• Round the number.
• Multiply the number by (the number of divisions ^ 10).
• Coerce the result to integer.

set theNumber to 7900
set theNumber to theNumber as real
set zeroCounter to 1
repeat until theNumber mod 10 is not 0.0
	set theNumber to theNumber / 10
	set zeroCounter to zeroCounter + 1
end repeat
set theNumber to round (theNumber / 10)
set roundedNumber to theNumber * (10 ^ zeroCounter) as integer

One could use Applescript’s text item delimiters property to achieve a result similar to that of Stefan’s but without the need for a repeat loop:

  • Create a text version of the integer
  • Split the text at the rightmost target digit at which the number should be rounded
  • Get the rightmost target digit position = (number of characters in the last of the split text items) + 1
  • Insert a decimal point in the text version of the integer before the rightmost target digit
  • Round that decimal value
  • Multiply the result by (10 ^ rightmost target digit position) to append the appropriate number of trailing zeros to the rounded number
  • Coerce the result to integer

It’s not clear from the original post whether the numbers should be rounded at the final “9” digit, the final nonzero digit, or something else, but this can be set simply by modifying targetDigits:


set targetDigits to {"9"} -- to round at the rightmost "9" digit
--or--
set targetDigits to {"5", "6", "7", "8", "9"} -- to round at the rightmost "5" thru "9" digit
--or--
set targetDigits to {"1", "2", "3", "4", "5", "6", "7", "8", "9"} -- to round at the rightmost nonzero digit (generating results identical to those of Stefan's algorithm)

set roundedNumber to theNumber
set paddedNum to "0" & theNumber
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, targetDigits}
set textItems to paddedNum's text items
set AppleScript's text item delimiters to tid
if textItems's length > 1 then
	set targetDigitPos to (textItems's last item's length) + 1
	set roundedNumber to (round ((paddedNum's text 1 thru -(targetDigitPos + 1)) & "." & paddedNum's text -targetDigitPos)) * (10 ^ targetDigitPos) as integer
end if

-- For theNumber = 59 --> roundedNumber = 60
-- For theNumber = 490 --> roundedNumber = 500
-- For theNumber = 7090 --> roundedNumber = 7100
-- For theNumber = 7900 --> roundedNumber = 8000

Timing tests reveal that Stefan’s algorithm runs about 20% faster than this algorithm if the numbers are rounded at the rightmost nonzero digit. If rounded at the rightmost “9” digit only, the two algorithms execute at nearly identical speeds.

Here’s an adaptation of Stefan’s script which only rounds where the input integer’s last non-zero digit is 9, which seems to be what Joy wants. The problem with the request, though, is obvious from the examples in the script: :confused:

on roundLast9(theNumber) -- theNumber is assumed to be a whole-number value.
	set n to theNumber
	set tenPower to 1
	repeat while n mod 10 is 0
		set n to n div 10
		set tenPower to tenPower * 10
	end repeat
	if (n mod 10 is 9) then set theNumber to (n + 1) * tenPower -- Positives only.
	-- if ((n mod 10) ^ 2 is 81.0) then set theNumber to (n / 10 as integer) * 10 * tenPower -- Positives or negatives.
	
	return theNumber
end roundLast9

roundLast9(70900) --> 71000
roundLast9(70950) --> 70950
roundLast9(70990) --> 71000