Apakah ada representasi data tunggal yang berfungsi untuk semua mata uang (bahkan yang berbeda dari Dolar, Euro, dan Pound)?


12

Saya dapat menemukan banyak pertanyaan tentang perpustakaan untuk digunakan untuk mewakili jumlah dalam beberapa mata uang. Dan tentang masalah tua mengapa Anda tidak harus menyimpan mata uang sebagai nomor poin mengambang IEEE 754. Tetapi sepertinya saya tidak dapat menemukan apa pun lagi. Tentunya ada banyak lagi yang perlu diketahui tentang mata uang dalam penggunaan dunia nyata. Saya khususnya tertarik pada apa yang perlu Anda ketahui untuk mewakilinya dalam penggunaan fisik (misalnya, dengan dolar, Anda tidak pernah memiliki ketepatan kurang dari $ 0,01, yang memungkinkan representasi sebagai bilangan bulat sen).

Tetapi sulit untuk membuat asumsi tentang seberapa fleksibelnya program Anda ketika satu-satunya mata uang yang Anda tahu adalah mata uang barat yang populer (seperti dolar, euro, dan pound). Apa lagi pengetahuan yang relevan dalam perspektif yang murni terprogram? Saya tidak peduli dengan topik pertobatan.

Khususnya, apa yang perlu kita ketahui untuk dapat menyimpan nilai dalam beberapa mata uang dan mencetaknya?


2
Tidak semua programmer bekerja di industri yang memanipulasi jumlah mata uang.
whatsisname

4
Oh tentu. Tapi itu bisa dikatakan tentang hampir semua hal. Saya pikir kita dapat mengasumsikan bahwa mereka yang menganggap pertanyaan ini bermanfaat adalah mereka yang bekerja dengan mata uang.
Kat

5
Saya telah melakukan banyak pekerjaan pengembangan untuk bank dan perusahaan jasa keuangan lainnya di NYC. Dan saya dapat menjamin Anda bahwa tidak ada jawaban "tertutup" untuk pertanyaan Anda. Anda mungkin juga bertanya, "berapa banyak matematika yang harus saya ketahui?" Sebagai contoh, pada tahun 1990-an harga saham naik dari delapan dan 256 ke desimal, membutuhkan banyak pemrograman ulang. Siapa yang bisa menduga itu akan terjadi? Anda hanya perlu memahami bisnis yang didukung aplikasi Anda, dan cara terbaik untuk merepresentasikan data (dalam hal ini mata uang) untuk mendukung kebutuhan bisnis tersebut.
John Forkosh

4
0,02 saya: Harga adalah satu hal. Mata uang adalah hal lain.
Machado

3
Saya pikir, Oh, pasti ada beberapa penyebut untuk semua mata uang. Tapi mungkin juga tidak. Penny sterling saat ini 1-100 pound, tetapi adalah 1-240 pound. Jadi Anda tidak hanya memiliki divisi 1/240, tetapi Anda memiliki tanggal peralihan, dan mungkin nilai tukar untuk pence lama belum beralih. en.wikipedia.org/wiki/Penny_sterling Jangan biarkan saya memulai dengan kerang cowry! en.wikipedia.org/wiki/Shell_money atau fakta bahwa uang membutuhkan kepercayaan untuk menjadi nyata: en.wikipedia.org/wiki/Money Pertanyaan yang bagus bahkan jika itu tidak cocok dengan StackExchange dengan baik!
GlenPeterson

Jawaban:


24

misalnya, dengan dolar, Anda tidak pernah memiliki ketepatan kurang dari $ 0,01

Oh benarkah? masukkan deskripsi gambar di sini

masalah lama mengapa Anda tidak harus menyimpan mata uang sebagai nomor floating point IEEE 754.

masukkan deskripsi gambar di sini

Silakan menyimpan inci dalam nomor floating point IEEE 754 . Mereka menyimpan persis seperti yang Anda harapkan.

Jangan ragu untuk menyimpan sejumlah uang dalam nomor floating point IEEE 754 yang dapat Anda simpan menggunakan kutu yang membagi penggaris menjadi pecahan satu inci.

Mengapa? Karena ketika Anda menggunakan IEEE 754 itulah cara Anda menyimpannya.

Hal tentang inci adalah mereka dibagi menjadi dua. Hal tentang sebagian besar jenis mata uang adalah mereka dibagi dalam sepuluh (beberapa jenis tidak tetapi mari kita tetap fokus).

Perbedaan ini tidak akan terlalu membingungkan kecuali bahwa, untuk sebagian besar bahasa pemrograman, input dan output dari angka-angka floating point IEEE 754 dinyatakan dalam desimal! Yang sangat aneh karena mereka tidak disimpan dalam desimal.

Karena ini, Anda tidak pernah bisa melihat bagaimana bit melakukan hal-hal aneh ketika Anda meminta komputer untuk menyimpan 0.1. Anda hanya melihat keanehan ketika Anda melakukan matematika melawannya dan itu memiliki kesalahan aneh.

Dari java efektif Josh Bloch :

System.out.println(1.03 - .42);

Menghasilkan 0.6100000000000001

Apa yang paling banyak diceritakan tentang ini bukanlah 1cara duduk di sebelah kanan. Ini angka aneh yang harus digunakan untuk mendapatkannya. Daripada menggunakan contoh yang paling populer 0.1, kita harus menggunakan contoh yang menunjukkan masalah dan menghindari pembulatan yang akan menyembunyikannya.

Misalnya, mengapa ini bekerja?

System.out.println(.01 - .02);

Menghasilkan -0.01

Karena kita beruntung.

Saya benci masalah yang sulit didiagnosis karena kadang-kadang saya "beruntung".

IEEE 754 tidak bisa menyimpan 0,1 dengan tepat. Tetapi jika Anda memintanya untuk menyimpan 0,1 dan kemudian meminta untuk mencetak maka itu akan menampilkan 0,1 dan Anda akan berpikir semuanya baik-baik saja. Ini tidak baik, tetapi Anda tidak dapat melihat itu karena pembulatan untuk kembali ke 0,1.

Beberapa orang mengacaukan heck out dari orang lain dengan menyebut perbedaan ini untuk memperbaiki kesalahan. Tidak, ini bukan kesalahan pembulatan. Pembulatan adalah melakukan apa yang seharusnya dan mengubah apa yang bukan desimal menjadi desimal sehingga dapat dicetak di layar.

Tapi ini menyembunyikan ketidakcocokan antara bagaimana nomor ditampilkan dan bagaimana disimpan. Kesalahan tidak terjadi ketika pembulatan terjadi. Itu terjadi ketika Anda memutuskan untuk memasukkan nomor ke dalam sistem yang tidak dapat menyimpannya dengan tepat dan menganggap itu disimpan tepat ketika tidak.

Tidak ada yang mengharapkan π untuk menyimpan secara tepat dalam kalkulator dan mereka berhasil bekerja dengan baik. Jadi masalahnya bukan tentang presisi. Ini tentang presisi yang diharapkan. Komputer menampilkan sepersepuluh 0.1sama dengan kalkulator kami, jadi kami berharap mereka menyimpan sepersepuluh dengan sempurna seperti yang dilakukan kalkulator kami. Mereka tidak melakukannya. Yang mengejutkan, karena komputer lebih mahal.

Mari saya tunjukkan ketidakcocokan:

masukkan deskripsi gambar di sini

Perhatikan bahwa 1/2 dan 0,5 berbaris dengan sempurna. Tapi 0,1 tidak berbaris. Tentu Anda bisa lebih dekat jika Anda terus membaginya dengan 2 tetapi Anda tidak akan pernah memukulnya dengan tepat. Dan kita membutuhkan semakin banyak bit setiap kali kita bagi dengan 2. Jadi, mewakili 0,1 dengan sistem apa pun yang membaginya dengan 2 membutuhkan jumlah bit yang tak terbatas. Hard drive saya tidak sebesar itu.

Jadi IEEE 754 berhenti mencoba ketika kehabisan bit. Yang bagus karena saya perlu ruang di hard drive saya untuk ... foto keluarga. Tidak benar-benar. Foto keluarga. : P

Bagaimanapun, apa yang Anda ketikkan dan apa yang Anda lihat adalah desimal (di sebelah kanan) tetapi yang Anda simpan adalah bicimal (di sebelah kiri). Terkadang itu sama persis. Terkadang tidak. Terkadang sepertinya mereka sama, padahal sebenarnya tidak. Itulah pembulatannya.

Khususnya, apa yang perlu kita ketahui untuk dapat menyimpan nilai dalam beberapa mata uang dan mencetaknya?

Tolong, jika Anda menangani uang berbasis desimal saya, jangan gunakan pelampung atau ganda.

Jika Anda yakin hal-hal seperti sepersepuluh uang tidak akan terlibat maka simpan saja uang itu. Jika Anda tidak mencari tahu unit terkecil dari mata uang ini akan menjadi dan menggunakannya. Jika Anda tidak bisa, gunakan sesuatu seperti BigDecimal .

Kekayaan bersih saya mungkin akan selalu cocok dengan integer 64 bit, tetapi hal-hal seperti BigInteger bekerja dengan baik untuk proyek-proyek yang lebih besar dari itu. Mereka lebih lambat dari tipe asli.

Mencari tahu bagaimana menyimpannya hanya setengah dari masalah. Ingat Anda juga harus bisa menampilkannya. Desain yang baik akan memisahkan kedua hal ini. Masalah sebenarnya dengan menggunakan pelampung di sini adalah kedua hal itu disatukan.

masukkan deskripsi gambar di sini


6
Saya tidak benar-benar mencari penjelasan lain mengapa IEEE 754 tidak bekerja untuk uang. Saya menyebutkan dalam OP bahwa ini telah dijelaskan dengan baik di tempat lain. Demikian pula, ada alasan saya menggunakan istilah "penggunaan fisik". Yaitu karena walaupun harga gas, nilai tukar saham, dll mungkin memiliki presisi yang sewenang-wenang, uang fisik (dan jumlah transaksi pengguna yang sangat besar) tidak melewati ratusan tempat (dan berbagai perangkat lunak hanya ingin mewakili apa yang dapat dibayar dengan uang fisik). Salah satu info yang saya bertanya-tanya adalah apakah ada mata uang yang masuk ke tempat desimal lebih.
Kat

3
"Keanehan" floating point tidak terbatas hanya pada separuh vs 1/10 dari. Aspek "floating point" dalam nama juga terkadang menyebabkan hasil yang tidak terduga.
whatsisname

6
Sebelum desimalisasi, mata uang Inggris adalah pound, shilling & pence, (£ sd), dengan £ 1 == 20s, 1s = 12d jadi £ 1 = 240d jadi 1d = 0,0046666666666 .. jadi bahkan tidak bisa direpresentasikan sebagai desimal. Sebelum bergabung dengan euro, Lira Italia mencapai 2.346,4 (pada tahun 2001) menjadi US $ sehingga hal-hal seperti gaji & harga rumah kadang-kadang mencapai batas atas pelampung presisi tunggal dan angka-angka ekonomi mencapai tingkat atas ganda.
Steve Barnes

2
Saya hanya akan berdebat / menunjukkan bahwa Mata Uang adalah satu hal, dan Harga adalah hal lain. Anda dapat memiliki presisi lebih dari $ 0,01 dalam harga, tetapi Anda tidak dapat membayar secara efektif, dengan presisi itu.
Machado

1
Juga foto keluarga . Pft. :)
Machado

10

Saya dapat menemukan banyak pertanyaan tentang perpustakaan untuk digunakan untuk mewakili jumlah dalam beberapa mata uang.

"Perpustakaan" tidak perlu kecuali perpustakaan standar bahasa Anda kurang dalam tipe data tertentu, seperti yang akan saya jelaskan.

Tentunya ada banyak lagi yang perlu diketahui tentang mata uang dalam penggunaan dunia nyata. Saya khususnya tertarik pada apa yang perlu Anda ketahui untuk mewakilinya dalam penggunaan fisik (misalnya, dengan dolar, Anda tidak pernah memiliki ketepatan kurang dari $ 0,01, yang memungkinkan representasi sebagai bilangan bulat sen).

Sederhananya, Anda membutuhkan desimal titik tetap , bukan desimal titik mengambang . Misalnya, kelas BigDecimal Java dapat digunakan untuk menyimpan jumlah mata uang. Bahasa modern lainnya memiliki tipe bawaan yang serupa, termasuk C # dan Python . Implementasinya beragam, tetapi biasanya menyimpan angka sebagai bilangan bulat, dengan lokasi desimal sebagai anggota data yang terpisah. Ini memberikan presisi yang tepat, bahkan ketika melakukan aritmatika yang akan memberikan sisa aneh (misalnya 0,0000001) dengan angka-angka floating point IEEE.

Khususnya, apa yang perlu kita ketahui untuk dapat menyimpan nilai dalam beberapa mata uang dan mencetaknya?

Ada beberapa poin penting.

  1. Gunakan tipe desimal yang sebenarnya daripada floating point.

  2. Memahami bahwa jumlah mata uang memiliki dua komponen: nilai (5,63) dan kode atau jenis mata uang (USD, CAD, GBP, EUR, dkk). Kadang-kadang Anda dapat mengabaikan kode mata uang, di lain waktu itu sangat penting. Bagaimana jika Anda bekerja pada sistem keuangan atau ritel / e-commerce yang memungkinkan banyak mata uang? Apa yang terjadi jika Anda mencoba mengambil uang dari pelanggan dalam CAD, tetapi mereka ingin membayar dengan MXN? Anda memerlukan jenis "uang" dengan kode mata uang dan jumlah mata uang untuk dapat mencampur nilai-nilai ini (juga nilai tukar, tetapi saya tidak ingin terlalu jauh dengan garis singgung). Pada saat yang sama, perangkat lunak keuangan pribadi saya tidak perlu khawatir tentang ini karena semuanya dalam USD ( dapat mencampur mata uang, tetapi saya tidak pernah perlu).

  3. Sementara mata uang mungkin memiliki unit fisik terkecil dalam praktiknya (CAD dan USD memiliki sen, JPY hanya ... Yen) dimungkinkan untuk menjadi lebih kecil. Jawaban CandiedOrange menunjukkan harga bahan bakar dalam sepersepuluh sen. Pajak properti saya dinilai sebagai pabrik per dolar, atau sepersepuluh sen (1/1000 dolar AS). Jangan batasi diri Anda hingga $ 0,01. Sementara Anda dapat menampilkan nilai-nilai itu sebagian besar waktu, jenis Anda harus memungkinkan lebih kecil (tipe desimal yang dirujuk di atas lakukan).

  4. Perhitungan menengah tentunya harus memungkinkan lebih banyak presisi daripada satu sen. Saya telah bekerja pada sistem ritel / e-commerce di mana nilai-nilai internal dibulatkan menjadi $ 0,00000001 secara internal. Ketepatan tanpa batas biasanya tidak didukung oleh tipe desimal (atau SQL) sehingga harus ada batasan. Misalnya, membagi 1/3 menggunakan BigDecimal Java akan mengeluarkan pengecualian tanpa ditentukan RoundingMode atau MathContext karena nilainya tidak dapat direpresentasikan secara tepat.

    Bagaimanapun, ini sangat penting dalam kasus-kasus tertentu. Mari kita asumsikan Anda memiliki pengguna dengan enam item di keranjang belanja, dan dia pergi untuk check out. Sistem Anda harus menghitung pajak, dan melakukannya per item karena item dapat dikenakan pajak berbeda. Jika Anda membulatkan pajak di setiap item, Anda mungkin mendapatkan kesalahan pembulatan sen pada tingkat transaksi / keranjang. Salah satu pendekatan untuk memperbaikinya adalah dengan menyimpan pajak ke lebih banyak tempat desimal per item, mendapatkan total untuk seluruh transaksi, dan kembali dan keliling setiap item sehingga pajak total benar (mungkin satu item dibulatkan ke atas, ke bawah lainnya).

Hal penting yang harus disadari dari semua ini adalah bahwa sesuatu yang sama pentingnya dengan pembulatan uang bisa sangat penting bagi orang yang tepat (misalnya, beberapa pelanggan saya di masa lalu yang harus membayar pajak penjualan pemerintah atas nama pelanggan mereka). Namun, ini semua adalah masalah yang diselesaikan. Ingatlah poin-poin di atas dan lakukan eksperimen sendiri, dan Anda akan belajar sambil melakukan.


Pada tanggal 2, saya pikir nilai tukar cukup untuk mendapatkan setidaknya nomornya sendiri. Anda harus mempertimbangkan bahwa tarif berubah seiring waktu, yang memiliki beberapa cara penanganan yang berbeda.
Izkata

2
+1. Juga, mata uang berubah seiring waktu. Di Brazil kami telah berulang kali mengubah mata uang selama tahun 80-an dan 90-an, memotong nol dan mengganti nama mata uang bila perlu karena inflasi di luar kendali. Itu berarti bahwa setiap aspek mata uang dapat berubah seiring waktu.
Machado

@Izkata tentu saja, saya telah bekerja pada sistem yang mengubah mata uang. Saya ingin menyentuh topik yang relevan. Namun, itu bukan fokus pertanyaan dan saya mungkin bisa mengetikkan jawaban lain selama ini tentang topik pertukaran mata uang.

'"Perpustakaan" tidak diperlukan kecuali perpustakaan standar bahasa Anda kurang dalam tipe data tertentu, seperti yang akan saya jelaskan.' Mata uang dapat memiliki separuh, seperempat, persepuluh, delapan, dll, yang berarti kita setidaknya memerlukan representasi desimal untuknya. Tetapi apakah kita sepenuhnya yakin bahwa tidak ada mata uang dengan bagian 1/3 dari seluruh?
Daniel McLaury

4

Satu tempat di mana banyak pengembang dihadapkan dengan representasi data tunggal untuk mata uang apa pun adalah untuk pembelian dalam aplikasi untuk aplikasi iOS. Pelanggan Anda dapat terhubung ke toko di hampir semua negara di dunia. Dan dalam situasi itu, Anda akan diberi harga pembelian yang terdiri dari angka presisi ganda , dan kode mata uang.

Anda harus sadar bahwa jumlahnya bisa besar. Ada mata uang di mana setara dengan katakanlah sepuluh dolar lebih dari 100.000 unit. Dan kami beruntung bahwa tidak ada mata uang seperti dolar Zimbabwe saat ini, di mana Anda dapat memiliki seratus triliun uang kertas!

Untuk menampilkan mata uang, Anda akan memerlukan beberapa perpustakaan - Anda tidak memiliki kesempatan untuk memperbaikinya sendiri. Tampilan tergantung pada dua hal: Kode mata uang, dan lokal pengguna. Pikirkan bagaimana dolar AS dan dolar Kanada akan ditampilkan dengan lokal AS dan lokal Kanada: Di AS, Anda memiliki $ vs CAN $, dan di Kanada Anda memiliki US $ vs $. Harapan yang dibangun ke dalam OS, atau Anda memiliki perpustakaan yang bagus.

Untuk perhitungan, perhitungan apa pun akan berakhir dengan langkah pembulatan. Anda harus mengetahui bagaimana Anda harus melakukan pembulatan itu secara legal . Itu bukan masalah pemrograman, itu masalah hukum. Misalnya, jika Anda menghitung PPN di Inggris, Anda harus menghitung pajak per item atau per baris item, dan membulatkannya menjadi uang. Apa yang Anda bulatkan tergantung pada mata uang. Tapi aturannya jelas tergantung pada negara. Anda tidak dapat mengharapkan bahwa perhitungan yang secara hukum benar di Inggris akan benar secara hukum di Jepang dan sebaliknya.


0

Khususnya, apa yang perlu kita ketahui untuk dapat menyimpan nilai dalam beberapa mata uang dan mencetaknya?

  • "to store values" : tipe data nomor titik tetap dan tipe mata uang. Saya pikir ini sangat jelas. Menyimpan ke nomor non-fixed-point bisa melibatkan beberapa pembulatan dan mengubah nilainya. Perhitungan mata uang akan menjadi masalah yang berbeda.
  • "to print out out" : lokal pengguna. Jika Anda beruntung, Anda mendapatkan perpustakaan standar untuk melakukan semuanya, misalnya simbol mata uang, pemisah ribuan, pemisah desimal, presisi, dll.

Beberapa contoh masalah yang terkait dengan lokal:

  • 100 USD dalam lokal AS harus $ 100,00, di lokal lain dengan titik sebagai pemisah desimal adalah US $ 100,00.
  • Beberapa negara menggunakan banyak sekali bukan ribuan untuk mengelompokkan angka, misalnya alih-alih 10.000,00 itu hanya akan menjadi 1.0000,00
  • Untuk alasan praktis, orang tidak mencetak semua angka untuk mata uang kecil, misal alih-alih $ 1.000.000.000,00, mereka hanya ingin Anda mencetak $ 1 miliar.

Masalah potensial lainnya adalah bahkan jika Anda menyimpan mata uang dengan benar dalam angka titik tetap, mungkin perlu dikonversi ke angka titik mengambang karena perpustakaan yang digunakan untuk mencetak hanya mendukung titik mengambang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.