Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is this right way of doing float to integer in bash, Or is there any other method ?

flotToint() {
    printf "%.0f\n" "$@"
}
share|improve this question
3  
What is "right"? –  Joseph R. Sep 6 '13 at 21:40
    
I just want to make sure.. is this right or is there better than this ? –  Rahul Patil Sep 6 '13 at 21:41
    
%.0f will round up or down. Is that what you want? You can use printf "%d\n" "$@" 2>/dev/null to chop the fraction. –  ott-- Sep 6 '13 at 23:56

3 Answers 3

up vote 9 down vote accepted

bash

In bash, that's probably as good as it gets. That uses a shell builtin. If you need the result in a variable, you could use command substitution, or the bash specific:

printf -v int %.0f "$float"

You could do:

float=1.23
int=${float%.*}

But that would remove the fractional part instead of giving you the nearest integer and that wouldn't work for values of $float like 1.2e9 or .12 for instance.

Also note that you might get unexpected behavior for instance in:

$ printf '%.0f\n' 1.5 2.5
2
2

Due to the internal representation of floats.

Also

$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560

You do get an integer, but chances are that you won't be able to use that integer anywhere.

POSIX

printf "%.0f\n" 1.1

is not POSIX as %f is not required to be supported by POSIX.

POSIXly, you can do:

f2i() {
  awk 'BEGIN{for (i=1; i<ARGC;i++)
   printf "%.0f\n", ARGV[i]}' "$@"
}

zsh

In zsh (which supports floating point arithmetics), you have the rint() math function to give you the nearest integer as a float (like in C) and int() to give you an integer from a float (like in awk). So you can do:

$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123

Or:

$ integer i=$((rint(5.678e2)))
$ echo $i
568

However note that while doubles can represent very large numbers, integers are much more limited.

$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808

ksh93

ksh93 is the other Bourne-like shell that supports floating point arithmetic. ksh93 optimises command substitution by using a pipe or forking when the commands are only builtin. So

i=$(printf '%.0f' "$f")

doesn't fork.

You can also do:

i=$((rint(f)))

But beware of:

$ echo $((rint(1e18)))
1000000000000000000
$ echo $((rint(1e19)))
1e+19

You could also do:

integer i=$((rint(f)))

But like for zsh:

$ integer i=1e18
$ echo $i
1000000000000000000
$ integer i=1e19
$ echo $i
-9223372036854775808
share|improve this answer

bc - An arbitrary precision calculator language

int(float) should looks like:

$ echo "$float/1" | bc 
1234

To round better use this:

$ echo "($float+0.5)/1" | bc 

Example:

$ float=1.49
$ echo "($float+0.5)/1" | bc 
1
$ float=1.50
$ echo "($float+0.5)/1" | bc 
2
share|improve this answer

install the beep program with:

aptitude install beep
or
apt-get install beep

and listen to the sine function like this:

1a. define the function in bash:

$ function sinus () 
{ 
    a=$1;
    b=$2;
    n=$3;
    f=$4;
    d=$(echo "scale=$f; ($b-$a)/$n"|bc);
    for m in $(seq 0 $n);
    do
        x=$(echo "scale=$f;$a+$m*$d"|bc);
        y=$(echo "scale=$f;s($x)"|bc -l);
        #printf "%0.${f}f\t" "$x";
        #printf "%0.${f}f\n" "$y";
        z=$(echo "scale=$f; 2300+2000*$y" | bc);
        beep -f "$z" -l 2 -d 0;
    done | column -t
}

2a. Call this function like this:

$ sinus 1 20 300 4

Note: 'sinus a b n f' means to listen the sound of sine (in radians) from a to b dividing the interval in n+1 equal parts using f decimals. There are more things than needed in the function because you can use them to plot or any other things. You can also write read a b n f instead of the initializations.

Also, very funny, crushing the cycles in the sine function more and more until the program can't stand it:

1b. define:

$ function sinus-inv () 
{ 
    a=$1; b=$2; n=$3; f=$4;
    d=$(echo "scale=$f; ($b-$a)/$n"|bc);
    for m in $(seq 1 $n);
    do
        x=$(echo "scale=$f;$a+$m*$d"|bc);
        y=$(echo "scale=$f;s(8000/($b-$x))"|bc -l);
        z=$(echo "scale=$f; 2300+2000*$y" | bc);
        beep -f "$z" -l 1 -d 0;
    done;
}

2b. Example call:

$ sinus-inv 1 100 1000 8
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.