To be clear, in echo 2.5 | awk '{print int($1+0.5)}'
in your question, that awk code is not rounding up to 3
, it's adding 0.5
and then rounding down to 3 (but it's already 3 so int()
isn't actually rounding it). If you started with 2.4
instead of 2.5
the result would be 2
, not 3
as you'd expect from rounding up, because int()
always rounds down.
Using any awk:
$ awk '
function ceil(x, y) { y=int(x); return(x>y ? y+1 : y) }
{ print ceil($0 * 1.03) }
' file
3165984979
1558923117
5131638250
1585582973
3270579768
5404428910
14789785075
If you use ,
rather than .
as the decimal point in your locale it is possible to use 1,03
instead of 1.03
in your calculation but I wouldn't recommend it (I'd recommend using LC_ALL=C
by default) as that requires different code in different awk variants and is not as straight-forward as it sounds, e.g. with GNU awk we need to add -N
to tell gawk to use your locale for this, and then write 1,03
as a string "1,03"
instead of a literal number and rely on using it in an arithmetic context (multiplying) to convert it to a number because a literal ,
means different things in an awk script:
$ LC_ALL='fr_FR' awk -N '
function ceil(x, y) { y=int(x); return(x>y ? y+1 : y) }
{ print ceil($0 * "1,03") }
' file
3165984979
1558923117
5131638250
1585582973
3270579768
5404428910
14789785075
See https://www.gnu.org/software/gawk/manual/gawk.html#Locale-influences-conversions for more information on that.
In general, though, what you're asking for is a ceil()
(for "ceiling") function as shown above. 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).
locale
return,?locale decimal_point