0

I am trying to create a ceiling function in bash that will take a number and round upwards as a ceiling function.

For instance: If shard_div is 3.2 rounded_up will be 4.

rounded_up=`echo $shard_div | awk '{printf("%d\n",$0+=$0<0?0:0.9)}'`

Where the problem is occuring is some shard_div variables are numbers like 0.5^-10 or 0.00001. When this occurs the rounded_up is 0.

I would prefer not to use an if statement, and the machines this is running on do not have Perl.

JNevill
  • 46,980
  • 4
  • 38
  • 63
Joseph P Nardone
  • 150
  • 2
  • 12
  • 1
    Your logic is incorrect :) It doesn't work for any number whose fractional part is less than 0.1. For example if `$shard_div` was `3.01`, the program will print `int(3.01 + 0.9)` = `int(3.91)` = `3`. – svsd Sep 04 '18 at 13:16
  • Any reason to not consider this as a duplicate of the question where the answer https://stackoverflow.com/a/2395053/3182664 seems to be what you're looking for? – Marco13 Sep 04 '18 at 13:30
  • Marco that question has no accepted answer, as well as many of the solutions do not work. That question was consulted and tested before asking this one. Kamil's solution solves many floating point division issues, and is therefore more elegant. – Joseph P Nardone Sep 04 '18 at 14:21

2 Answers2

1

Use bc. It is a little robust, but works.

rounded_up=$(echo "scale=0; v=$shard_div; v=6; if (v%1 != 0) v = (v + 1); v / 1" | bc)

The / 1 is needed, otherwise bc doesn't scale. The v%1 == 0 case needs to be handled, otherwise whole number will be scaled up too (like v=5; 5+1 -> 6)

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

In awk:

$ awk '{print int($1) + ( $1!=int($1) && $1>=0 )}'

Some tests:

$ echo 0 | awk '{print int($1)+($1!=int($1)&&$1>=0)}'
0
$ echo 0.1 | awk '{print int($1)+($1!=int($1)&&$1>=0)}'
1
$ echo 1 | awk '{print int($1)+($1!=int($1)&&$1>=0)}'
1
$ echo -1 | awk '{print int($1)+($1!=int($1)&&$1>=0)}'
-1
$ echo -1.1 | awk '{print int($1)+($1!=int($1)&&$1>=0)}'
-1
James Brown
  • 36,089
  • 7
  • 43
  • 59