Contoh singkat tentang apa yang saya inginkan menggunakan bash scripting:
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
echo "scale=2; $float/1.18" |bc -l
read -p "Press any key to continue..."
bash scriptname.sh
Dengan asumsi bahwa harganya adalah: 48,86 Jawabannya adalah: 41,406779661 (41,40 sebenarnya karena saya menggunakan scale=2;
)
Pertanyaan saya adalah: Bagaimana saya membulatkan desimal kedua untuk menunjukkan jawaban dengan cara ini ?: 41.41
bc
tidak dapat mencapai apa yang diminta (atau setidaknya pertanyaan yang saya tanyakan ketika saya menemukan posting ini), yaitu bagaimana cara membulatkan desimal menggunakanbc
(yang kebetulan dipanggil olehbash
).r()
fungsi, sehingga Anda dapat menggunakannyabc -le "r($float/1.18, 2)"
.Jawaban:
Fungsi bash round:
Digunakan dalam contoh kode Anda:
Semoga beruntung: o)
sumber
-0.5
$2 = 3
saya harus menggunakanecho $(env printf %.3f $(echo "scale=3;((1000*$1)+0.5)/1000" | bc))
. Pikirkan env sebelum printf! Ini akan mengajari Anda lagi bahwa selalu penting untuk memahami apa yang Anda salin dari tempat lain.if [
echo "$ 1/1" | bc` -gt 0] `- apakah ada cara yang lebih elegan untuk memeriksa (kecuali menguraikan string untuk" - ")?Solusi paling sederhana:
sumber
+0.5
. Cobalahprintf "%.2f\n" "$(bc -l <<<"48.86/1.18")" "$(bc -l <<<"-48.86/1.18")"
dan Anda akan mendapatkan41.41
dan-41.41
.echo "$float/1.18" | bc -l | xargs printf %.2f
bash: printf: 1.69491525423728813559: invalid number
:, tergantung pada lokal.Bash / awk rounding:
Jika Anda memiliki python, Anda dapat menggunakan sesuatu seperti ini:
sumber
echo "$float" |awk '{printf "%.2f", $1/1.18}'
akan melakukan matematika yang diminta pertanyaan untuk percision yang diminta dari seratus. Itu sebanyak "menggunakan bash" sebagaibc
panggilan dalam pertanyaan.python -c "print(round($num))"
mananum=4.678923
. Tidak perlu bercanda dengan stdin. Anda juga dapat bulat untuk n digit suka begitu:python -c "print(round($num, $n))"
.echo 5 | python -c "print int(round((float(raw_input())/2)-0.5))"
(Ketika + akan mengumpulkan dan - bulat ke bawah).Ini solusi murni bc. Aturan pembulatan: pada +/- 0,5, bulatkan dari nol.
Masukkan skala yang Anda cari dalam $ result_scale; matematika Anda seharusnya berada di tempat $ MATH berada di daftar perintah bc:
sumber
MATH=-0.34;result_scale=1;bc <<MATH
, #ObjectiveAndClear: 5 seperti yang dijelaskan di sini :)Saya tahu ini pertanyaan lama, tapi saya punya solusi murni 'bc' tanpa 'jika' atau cabang:
Gunakan suka
bcr '2/3' 5
ataubcr '0.666666' 2
-> (ekspresi diikuti oleh skala)Itu mungkin karena dalam bc (seperti C / C ++) itu diperbolehkan untuk mencampur ekspresi logis dalam perhitungan Anda. Ekspresi
((t>0)-(t<0))/2)
akan mengevaluasi ke +/- 0,5 tergantung pada tanda 't' dan karenanya menggunakan nilai yang tepat untuk pembulatan.sumber
bcr "5 / 2" 0
kembali2
bukan3
. Apakah saya melewatkan sesuatu?Ini sebenarnya sederhana: tidak perlu menambahkan secara eksplisit varian "-0,5" yang telah di-hardcod untuk angka negatif. Secara matematis, kita hanya akan menghitung nilai absolut dari argumen dan tetap menambahkan 0,5 seperti biasa. Tetapi karena kita (sayangnya) tidak memiliki
abs()
fungsi bawaan yang kita miliki (kecuali kita kode satu), kita hanya akan meniadakan argumen jika negatif.Selain itu, terbukti sangat rumit untuk bekerja dengan hasil bagi sebagai parameter (karena untuk solusi saya, saya harus dapat mengakses dividen dan pembagi secara terpisah). Inilah sebabnya mengapa skrip saya memiliki parameter ketiga tambahan.
sumber
echo .. |
, shell aritmatika, apa gunanyaecho $()
? Ini mudah dijelaskan: string Anda di sini akan selalu membutuhkan direktori yang dapat ditulis/tmp
! Dan solusi saya juga akan bekerja pada lingkungan read-only, misalnya sebuah shell root darurat di mana/
adalah tidak selalu ditulis secara default. Jadi ada alasan bagus mengapa saya membuat kode seperti itu.echo $()
dibutuhkan? Itu dan lekukan mendorong suntingan saya, herestrings baru saja terjadi.echo $()
yang sudah terlambat untuk diperbaiki sebenarnya adalah garis kedua dari belakang, lol. Terimakasih atas peringatannya. Setidaknya yang satu ini memang terlihat jauh lebih baik sekarang, saya tidak dapat menyangkal. Bagaimanapun, saya menyukai logika dalam hal ini. Banyak hal boolean, "not" berlebihan (yang pasti akan meledakkan kode sebesar 50 persen).Saya masih mencari
bc
jawaban murni untuk cara membulatkan hanya satu nilai dalam suatu fungsi, tapi inilahbash
jawaban murni :Pada dasarnya, ini dengan hati-hati mengekstraksi desimal, mengalikan semuanya dengan 100 miliar (10¹⁰,
10**10
dalambash
), menyesuaikan presisi dan pembulatan, melakukan pembagian aktual, membagi kembali ke besaran yang sesuai, dan kemudian memasukkan kembali desimal.Selangkah demi selangkah:
The
embiggen()
ditunjuk fungsi dipotong bulat bentuk argumen untuk$int
dan menyimpan nomor setelah titik di$fraction
. Jumlah digit fraksional dicatat dalam$precision
. Matematika dikalikan 10¹⁰ dengan gabungan dari$int
dan$fraction
kemudian menyesuaikannya agar sesuai dengan presisi (misalnyaembiggen 48.86
menjadi 10¹⁰ × 4886/100 dan menghasilkan488600000000
488.600.000.000).Kami menginginkan ketepatan akhir dari seratus, jadi kami gandakan angka pertama dengan 100, tambahkan 5 untuk tujuan pembulatan, dan kemudian bagi angka kedua. Tugas ini
$answer
membuat kita seratus kali jawaban terakhir.Sekarang kita perlu menambahkan titik desimal. Kami menetapkan
$int
nilai baru untuk$answer
mengecualikan dua digit terakhirnya, laluecho
dengan titik dan$answer
tidak termasuk$int
nilai yang sudah diurus. (Jangankan bug yang menyoroti sintaksis yang membuat ini tampak seperti komentar)(Bashism: exponentiation bukan POSIX, jadi ini adalah bashism. Solusi POSIX murni akan membutuhkan loop untuk menambahkan nol daripada menggunakan kekuatan sepuluh. Juga, "embiggen" adalah kata yang sangat cromulant.)
Salah satu alasan utama yang saya gunakan
zsh
sebagai shell saya adalah bahwa ia mendukung matematika floating point. Solusi untuk pertanyaan ini cukup mudah dizsh
:(Saya ingin melihat seseorang menambahkan komentar pada jawaban ini dengan trik untuk mengaktifkan aritmatika floating point
bash
, tetapi saya cukup yakin bahwa fitur seperti itu belum ada.)sumber
jika Anda memiliki hasilnya, misalnya pertimbangkan 2.3747888
Yang harus Anda lakukan adalah:
ini membulatkan angka dengan benar contoh:
desimal dihilangkan oleh
bc
dan jadi dibulatkan menjadi 2 seperti seharusnyasumber
Saya harus menghitung total durasi koleksi file audio.
Jadi saya harus:
A. dapatkan durasi untuk setiap file ( tidak ditampilkan )
B. menjumlahkan semua durasi (masing-masing dalam
NNN.NNNNNN
(fp) detik)C. jam terpisah, menit, detik, subseconds.
D. output string HR: MIN: SEC: FRAMES, di mana frame = 1/75 detik.
(Frame berasal dari kode SMPTE yang digunakan di studio.)
A: gunakan
ffprobe
dan parsing garis durasi ke nomor fp (tidak ditampilkan)B:
C:
D:
sumber
Ini versi singkat dari skrip Anda, diperbaiki untuk memberikan hasil yang Anda inginkan:
Perhatikan bahwa pembulatan ke bilangan bulat terdekat sama dengan menambahkan 0,5 dan mengambil lantai, atau pembulatan ke bawah (untuk angka positif).
Juga, faktor skala diterapkan pada saat operasi; jadi (ini adalah
bc
perintah, Anda dapat menempelkannya ke terminal Anda):sumber
Implementasi BC murni seperti yang diminta
define ceil(x) { auto os,xx;x=-x;os=scale;scale=0 xx=x/1;if(xx>x).=xx-- scale=os;return(-xx) }
jika Anda memasukkannya ke dalam file bernama functions.bc maka Anda dapat menambahkannya
echo 'ceil(3.1415)' | bc functions.bc
Kode untuk implementasi bc ditemukan di http://phodd.net/gnu-bc/code/funcs.bc
sumber
sumber
Anda dapat menggunakan awk, tidak perlu pipa:
Tetapkan harga sebelumnya dengan variabel lingkungan
PRICE=<val>
.Kemudian panggil awk -
$PRICE
akan masuk ke awk sebagai variabel awkprice
.Ini kemudian dibulatkan ke 100 terdekat dengan +,005.
Opsi format printf
%.2f
membatasi skala hingga dua tempat desimal.Jika Anda harus sering melakukan ini, cara ini jauh lebih efisien daripada jawaban yang dipilih:
sumber