Roundup function in Unix

≡放荡痞女 提交于 2021-02-08 03:49:03

问题


I have a requirement as below

121.36
121.025
121.1
121.000

Desired output

122
122
122
121

Command used

awk -F"." '{if($8>0){print $11}}'

回答1:


What you're asking for is a ceil() (for "ceiling") function. It's important to include zero and negative numbers in your example when you're looking for any kind of rounding function as it's easy to get them wrong so using this input file:

$ cat file
1.999999
1.0
0.000001
0
-0.000001
-1.0
-1.999999

we can test a ceil() function:

$ awk 'function ceil(x, y){y=int(x); return(x>y?y+1:y)} {print $0,ceil($0)}' file
1.999999 2
1.0 1
0.000001 1
0 0
-0.000001 0
-1.0 -1
-1.999999 -1

and the opposite floor() function:

$ awk 'function floor(x, y){y=int(x); return(x<y?y-1:y)} {print $0,floor($0)}' file
1.999999 1
1.0 1
0.000001 0
0 0
-0.000001 -1
-1.0 -1
-1.999999 -2

The above works because int() truncates towards zero (from the GNU awk manual):

int(x)
    Return the nearest integer to x, located between x and zero and
    truncated toward zero. For example, int(3) is 3, int(3.9) is 3,
    int(-3.9) is -3, and int(-3) is -3 as well.

so int() of a negative number already does what you want for a ceiling function, i.e. round up, and you just have to add 1 to the result if int() rounded down a positive number.

I used 0.000001, etc. in the samples to avoid people getting a false positive testing a solution that adds some number like 0.9 and then int()ing.

Also note that ceil() could be abbreviated to:

function ceil(x){return int(x)+(x>int(x))}

but I wrote it as above for clarity (it's not clear/obvious that the result of x>int(x) is 1 or 0) and efficiency (only call int() once instead of twice).




回答2:


I was trying to find a way to do this in plain bash, but since bash can only do integer arithmetic I failed. You do need another language to work with you here.

I would write a shell function as a wrapper around that other langugage. For example:

$ ceil() { perl -MPOSIX=ceil -lpe '$_ = ceil($_)'; }

$ ceil <<END
121.36
121.025
121.1
121.000
0.1
0
-0.1
-3.0
-3.1
END

outputs

122
122
122
121
1
0
0
-3
-3

Any other language will do: ceil() { ruby -ne 'puts $_.to_f.ceil'; }



来源:https://stackoverflow.com/questions/37432680/roundup-function-in-unix

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!