Anda dapat memeriksa bagian bilangan bulat dan pecahan secara terpisah:
#!/bin/bash
min=12.45
val=12.35
if (( ${val%%.*} < ${min%%.*} || ( ${val%%.*} == ${min%%.*} && ${val##*.} < ${min##*.} ) )) ; then
min=$val
fi
echo $min
Seperti dikatakan Fered dalam komentar, itu hanya berfungsi jika kedua angka memiliki bagian fraksional dan kedua bagian fraksional memiliki jumlah digit yang sama. Berikut adalah versi yang berfungsi untuk integer atau fraksional dan operator bash apa pun:
#!/bin/bash
shopt -s extglob
fcomp() {
local oldIFS="$IFS" op=$2 x y digitx digity
IFS='.' x=( ${1##+([0]|[-]|[+])}) y=( ${3##+([0]|[-]|[+])}) IFS="$oldIFS"
while [[ "${x[1]}${y[1]}" =~ [^0] ]]; do
digitx=${x[1]:0:1} digity=${y[1]:0:1}
(( x[0] = x[0] * 10 + ${digitx:-0} , y[0] = y[0] * 10 + ${digity:-0} ))
x[1]=${x[1]:1} y[1]=${y[1]:1}
done
[[ ${1:0:1} == '-' ]] && (( x[0] *= -1 ))
[[ ${3:0:1} == '-' ]] && (( y[0] *= -1 ))
(( ${x:-0} $op ${y:-0} ))
}
for op in '==' '!=' '>' '<' '<=' '>='; do
fcomp $1 $op $2 && echo "$1 $op $2"
done
0.5
dan0.06
). Anda sebaiknya menggunakan alat yang sudah mengerti notasi desimal.1.00000000000000000000000001
lebih besar dari2
.Bash tidak mengerti aritmatika floating point. Ini memperlakukan angka yang mengandung titik desimal sebagai string.
Gunakan awk atau bc sebagai gantinya.
Jika Anda berniat melakukan banyak operasi matematika, mungkin lebih baik mengandalkan python atau perl.
sumber
Anda dapat menggunakan paket num-utils untuk manipulasi sederhana ...
Untuk matematika yang lebih serius, lihat tautan ini ... Ini menjelaskan beberapa opsi, misalnya.
Contoh dari
numprocess
Ini adalah
bash
retas ... Itu menambahkan 0's ke integer untuk membuat perbandingan string kiri-ke-kanan bermakna. Potongan kode khusus ini mengharuskan min dan val benar-benar memiliki titik desimal dan setidaknya satu digit desimal.keluaran:
sumber
Untuk perhitungan sederhana pada angka floating point (+ - * / dan perbandingan), Anda dapat menggunakan awk.
Atau, jika Anda memiliki ksh93 atau zsh (bukan bash), Anda dapat menggunakan aritmatika bawaan shell Anda, yang mendukung angka floating point.
Untuk perhitungan floating point lebih lanjut, cari bc . Ini benar-benar bekerja pada angka fixpoint presisi arbitrer.
Untuk mengerjakan tabel angka, lihat R ( contoh ).
sumber
Gunakan pengurutan angka
Perintah
sort
memiliki opsi-g
(--general-numeric-sort
) yang dapat digunakan untuk perbandingan pada<
, "kurang dari" atau>
, "lebih besar dari", dengan menemukan minimum atau maksimum.Contoh-contoh ini menemukan minimum:
Mendukung E-Notation
Ini bekerja dengan notasi angka floating point yang cukup umum, seperti dengan E-Notation
Perhatikan
E-10
, membuat angka pertama0.000000001245
, memang kurang dari10.35
.Dapat dibandingkan dengan tak terbatas
Standar floating point, IEEE754 , mendefinisikan beberapa nilai khusus. Untuk perbandingan ini, yang menarik adalah
INF
untuk tak terbatas. Ada juga infinity negatif; Keduanya merupakan nilai yang didefinisikan dengan baik dalam standar.Untuk menemukan penggunaan maksimum
sort -gr
sebagai gantinyasort -g
, membalikkan urutan pengurutan:Operasi perbandingan
Untuk mengimplementasikan
<
perbandingan ("kurang dari"), sehingga dapat digunakan dalamif
dll, bandingkan nilai minimum dengan salah satu dari nilai-nilai tersebut. Jika minimum sama dengan nilai, dibandingkan dengan teks , itu lebih kecil dari nilai lainnya:sumber
a == min(a, b)
sama dengana <= b
. Perlu dicatat bahwa ini tidak memeriksa kurang dari itu. Jika Anda ingin melakukan itu, Anda perlu memeriksaa == min(a, b) && a != max(a, b)
, dengan kata laina <= b and not a >= b
Cukup gunakan
ksh
(ksh93
tepatnya) atauzsh
, yang keduanya secara alami mendukung aritmatika floating point:Sunting: Maaf, saya ketinggalan
ksh93
sudah disarankan. Menjaga jawaban saya hanya untuk memperjelas skrip yang diposting dalam pertanyaan pembuka dapat digunakan tanpa perubahan di luar saklar shell.Sunting2: Catatan yang
ksh93
mengharuskan konten variabel konsisten dengan lokal Anda, yaitu dengan lokal Perancis, koma bukan titik harus digunakan:Solusi yang lebih kuat adalah dengan menetapkan lokal di awal skrip untuk memastikan itu akan berfungsi terlepas dari lokal pengguna:
sumber
.
(jadi tidak di separuh dunia tempat pemisah desimal berada,
).zsh
tidak memiliki masalah itu.LC_ALL
, itu juga berarti bahwa angka tidak akan ditampilkan (atau diinput) dalam format yang disukai pengguna. Lihat unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/… untuk pendekatan yang berpotensi lebih baik..
.Itu menggunakan
dc
kalkulator untuks
merobek nilai$min
dalam registera
dand
meningkatkan nilai$val
ke atas tumpukan eksekusi utamanya. Kemudianl
ists isinyaa
ke atas tumpukan, pada titik yang terlihat seperti:The
<
muncul atas dua entri dari tumpukan dan membandingkan mereka. Jadi tumpukan itu terlihat seperti:Jika entri atas kurang dari yang kedua ke atas itu mendorong konten
a
ke atas, sehingga tumpukan terlihat seperti:Atau tidak melakukan apa-apa dan tumpukan masih terlihat seperti:
Kemudian itu hanya
p
merusak entri tumpukan atas.Jadi untuk masalah Anda:
Tapi:
sumber
Mengapa tidak menggunakan yang lama, bagus
expr
?Sintaks contoh:
Untuk ekspresi sebenarnya , kode keluar expr adalah 0, dengan string '1' dikirim ke stdout. Membalikkan untuk yang salah ekspresi .
Saya sudah memeriksa ini dengan GNU dan FreeBSD 8 expr.
sumber
expr 1.09 '<' -1.1
akan mencetak1
dan keluar dengan0
(sukses).Untuk memeriksa apakah dua (mungkin pecahan) angka dalam urutan,
sort
apakah (cukup) portabel:Namun, jika Anda benar-benar ingin menjaga nilai minimum diperbarui, maka Anda tidak perlu
if
. Sortir angkanya, dan selalu gunakan yang pertama (paling tidak):sumber
Biasanya saya melakukan hal serupa dengan kode python tertanam:
sumber
sumber