Bit of a math question

I have a number, say 174. I need to write bash code that will find the first larger number that ends in 99. That would be 199 in this case. If the number were 1263, I would be looking for 1299, for 175438, I would want 175499, etc.

If the numbers were always three digit, I could just grab the first digit and add 99.
NEW_NUMBER=${OLD_NUMBER:0:1}'99'

I guess what I would want to do is to just remove the last two chars and replace with 99.
NEW_NUMBER=${OLD_NUMBER:0:-2}'99'

Does that look right??

LMHmedchem

Longhand using OSX 10.7.5, default bash terminal...

Last login: Fri Sep  5 20:24:17 on ttys000
AMIGA:barrywalker~> x=1234567
AMIGA:barrywalker~> y=99
AMIGA:barrywalker~> z=${x:0:$((${#x}-2))}$y
AMIGA:barrywalker~> echo $z
1234599
AMIGA:barrywalker~> _

A minor nitpick - suppose your number is 123499. wisecrackers code will return 123499. Is that the NEXT larger number ending in 99, after 123499? You get to decide.

This kind of thing is sometimes called an edge condition.

BTW wisecracker, nice effort.

Try

num=174
echo $(((num/100+1)*100-1))

scrutinizer's code - good but with the same problem it looks like....

What I am getting at is: problem as stated requires the addition of 1 to the starting number.

Crude example:

num=199
num=$(( $num + 1 ))
echo $(((num/100+1)*100-1))

That could be remedied like this:

echo $((((num+1)/100+1)*100-1))

@scrutinizer - absolutely, but I'm trying to get the OP to see your point.

Sorry for the delay, I went to the store and came back to find allot of very nice posts. After thinking about it, if the first number happens to end in *99,

FIRST_NUMBER='199'

then I would want 299 for my second number and not a repeat of 199.

So I guess this code will do what I need,

SECOND_NUMBER=$((((FIRST_NUMBER+1)/100+1)*100-1))

I plugged this into my script and I am getting the behavior I expect.

Is there some reason why my thought of just replacing the last two chars is ill conceived? The code I posted didn't work and I was getting a substring expression < 0 error.

I guess what I would have done here would have been to test $FIRST_NUMBER,

if [ "$FIRST_NUMBER" == "$SECOND_NUMBER" ]; then
   let "SECOND_NUMBER=$FIRST_NUMBER+100"
fi

to make sure I didn't end up in the same place, but it is nice to do this in one step.

LMHmedchem

The negative value is only possible in bash 4. Probably your bash is too old..

bash3$ num=1478; echo ${num:0:-2}99
-bash: -2: substring expression < 0

But even with bash 4 it would be a problem if FIRST_NUMBER is a single digit..

bash4-4.2$ num=1478; echo ${num:0:-2}99
1499
bash4-4.2$ num=147; echo ${num:0:-2}99
199
bash4-4.2$ num=14; echo ${num:0:-2}99
99
bash4-4.2$ num=1; echo ${num:0:-2}99
bash4: -2: substring expression < 0

Of course the value would still need to be corrected by one..

Hi Scrutinizer...

Then pad it with a space...

Last login: Fri Sep  5 22:52:07 on ttys000
AMIGA:barrywalker~> x=" 9"
AMIGA:barrywalker~> y=99
AMIGA:barrywalker~> z=${x:0:$((${#x}-2))}$y
AMIGA:barrywalker~> echo $z
99
AMIGA:barrywalker~> x=" 29"
AMIGA:barrywalker~> y=99
AMIGA:barrywalker~> z=${x:0:$((${#x}-2))}$y
AMIGA:barrywalker~> echo $z
99
AMIGA:barrywalker~> x=" 219"
AMIGA:barrywalker~> z=${x:0:$((${#x}-2))}$y
AMIGA:barrywalker~> y=99
AMIGA:barrywalker~> echo $z
299
AMIGA:barrywalker~> x="-9"
AMIGA:barrywalker~> y=99
AMIGA:barrywalker~> z=${x:0:$((${#x}-2))}$y
AMIGA:barrywalker~> echo $z
99
AMIGA:barrywalker~> _

All of the responses so far are assuming that the OLD_NUMBER is non-negative. If OLD_NUMBER can be less than -99, it is a little more complicated, but I think this works:

NEW_NUMBER=$((((OLD_NUMBER<=-100)*(OLD_NUMBER/100*100+1))+((OLD_NUMBER>-100)*((((OLD_NUMBER+1)/100)+1)*100-1))))

When put into a loop like this:

for OLD_NUMBER in "$@"
do
	NEW_NUMBER=$((((OLD_NUMBER<=-100)*(OLD_NUMBER/100*100+1))+((OLD_NUMBER>-100)*((((OLD_NUMBER+1)/100)+1)*100-1))))
	printf '%s -> %d\n' "$OLD_NUMBER" "$NEW_NUMBER"
done

and invoked as:

next99 1298 1299 1300 -1298 -1299 -1300 -99 99 0 -100

with either bash or ksh , it produces:

1298 -> 1299
1299 -> 1399
1300 -> 1399
-1298 -> -1199
-1299 -> -1199
-1300 -> -1299
-99 -> 99
99 -> 199
0 -> 99
-100 -> -99

For non-negative numbers, try

echo $((NUM+100-(NUM+1)%100))