it-swarm-id.com

Gunakan Float atau Desimal untuk Aplikasi Akuntansi Jumlah Dolar?

Kami sedang menulis ulang Sistem Akuntansi lawas kami dalam VB.NET dan SQL Server. Kami membawa tim baru .NET/SQL Programmer untuk melakukan penulisan ulang. Sebagian besar sistem sudah selesai dengan jumlah Dolar menggunakan Mengapung. Bahasa sistem warisan, saya program dalam, tidak memiliki Float jadi saya mungkin akan menggunakan Desimal.

Apa rekomendasi Anda?

Haruskah Float atau tipe data Desimal digunakan untuk jumlah dolar?

Apa saja pro dan kontra untuk keduanya?

Satu Con yang disebutkan dalam scrum harian kami adalah Anda harus berhati-hati ketika menghitung jumlah yang mengembalikan hasil yang melebihi dua posisi desimal. Sepertinya Anda harus membulatkan jumlahnya menjadi dua posisi desimal.

Con lainnya adalah semua tampilan dan jumlah yang dicetak harus memiliki Pernyataan Format yang menunjukkan dua posisi desimal. Saya perhatikan beberapa kali di mana ini tidak dilakukan dan jumlahnya tidak terlihat benar. (mis. 10.2 atau 10.2546)

Pro adalah Float hanya membutuhkan 8 byte pada disk di mana Desimal akan memakan 9 byte (Desimal 12,2) 

74
Gerhard Weiss
41
Nakilon

Pertama, Anda harus membaca ini Apa Yang Harus Ketahui Setiap Ilmuwan Komputer Tentang Aritmatika Floating Point . Maka Anda harus benar-benar mempertimbangkan untuk menggunakan beberapa jenis titik tetap/angka presisi arbitrer paket (mis. Java BigNum, modul desimal python) jika tidak Anda akan berada dalam dunia yang terluka. Kemudian mencari tahu apakah menggunakan tipe desimal SQL asli sudah cukup. 

Mengapung/ganda ada (ed) untuk mengekspos cepat x87 fp yang sekarang cukup usang. Jangan menggunakannya jika Anda peduli dengan keakuratan perhitungan dan/atau tidak sepenuhnya mengompensasi keterbatasan mereka.

22
Rich Schuler

Sama seperti peringatan tambahan, SQL Server dan .Net framework menggunakan algoritma default yang berbeda untuk pembulatan. Pastikan Anda memeriksa parameter MidPointRounding di Math.Round (). Kerangka Bersih. Menggunakan algoritma Bankir secara default dan SQL Server menggunakan Pembulatan Algoritma Simetris. Lihat artikel Wikipedia di sini

10
Darrel Miller

Tanyakan akuntan Anda! Mereka akan menyukai Anda karena menggunakan float. Seperti seseorang yang diposting sebelumnya, gunakan float ONLY jika Anda tidak peduli dengan akurasi. Meskipun saya akan selalu menentangnya dalam hal uang.

Dalam perangkat lunak akuntansi TIDAK dapat diterima pelampung. Gunakan desimal dengan 4 poin desimal.

7
Ricardo C

Floating point memiliki angka irasional yang tidak terduga.

Misalnya Anda tidak dapat menyimpan 1/3 sebagai desimal, itu akan menjadi 0,3333333333 ... (dan seterusnya)

Mengapung sebenarnya disimpan sebagai nilai biner dan kekuatan 2 eksponen.

Jadi 1,5 disimpan sebagai 3 x 2 ke -1 (atau 3/2)

Menggunakan basis-2 eksponen ini membuat beberapa bilangan irasional ganjil, misalnya:

Konversikan 1.1 ke float dan kemudian konversikan kembali, hasil Anda akan menjadi seperti: 1.0999999999989

Ini karena representasi biner dari 1.1 sebenarnya 154811237190861 x 2 ^ -47, lebih dari pegangan ganda.

Lebih lanjut tentang masalah ini di blog saya , tetapi pada dasarnya, untuk penyimpanan, Anda lebih baik dengan desimal.

Pada Microsoft SQL server Anda memiliki tipe data money - ini biasanya yang terbaik untuk penyimpanan keuangan. Itu akurat untuk 4 posisi desimal.

Untuk perhitungan, Anda memiliki lebih banyak masalah - ketidaktepatan adalah sebagian kecil, tetapi memasukkannya ke dalam fungsi daya dan dengan cepat menjadi signifikan. 

Namun desimal tidak terlalu bagus untuk matematika apa pun - misalnya, tidak ada dukungan asli untuk kekuatan desimal, misalnya.

6
Keith

Sedikit latar belakang di sini ....

Tidak ada sistem bilangan yang dapat menangani semua bilangan real secara akurat. Semua memiliki keterbatasan mereka, dan ini termasuk standar IEEE floating point dan desimal yang ditandatangani. Titik apung IEEE lebih akurat per bit yang digunakan, tetapi itu tidak masalah di sini.

Angka-angka keuangan didasarkan pada praktik kertas dan pena berabad-abad, dengan konvensi terkait. Mereka cukup akurat, tetapi, yang lebih penting, mereka direproduksi. Dua akuntan yang bekerja dengan berbagai angka dan angka harus muncul dengan angka yang sama. Setiap ruang untuk perbedaan adalah ruang untuk penipuan.

Oleh karena itu, untuk perhitungan finansial, jawaban yang tepat adalah apa pun yang memberikan jawaban yang sama dengan CPA yang ahli dalam hitung. Ini adalah aritmatika desimal, bukan IEEE floating point.

5
David Thornley

Gunakan tipe desimal SQL server.

Jangan gunakan uang atau float.

uang menggunakan 4 tempat desimal, lebih cepat daripada menggunakan desimal TETAPI menderita beberapa masalah yang jelas dan beberapa tidak begitu jelas dengan pembulatan ( lihat masalah koneksi ini

5
Mitch Wheat

Apa yang saya sarankan adalah menggunakan bilangan bulat 64 bit yang menyimpan semuanya dalam sen.

5
Joshua

Mengapung bukan representasi yang tepat, masalah presisi mungkin terjadi, misalnya ketika menambahkan nilai yang sangat besar dan sangat kecil. Itu sebabnya tipe desimal direkomendasikan untuk mata uang, meskipun masalah presisi mungkin cukup langka.

Untuk memperjelas, tipe 12,2 desimal akan menyimpan 14 digit itu dengan tepat, sedangkan float tidak akan karena menggunakan representasi biner secara internal. Misalnya, 0,01 tidak dapat direpresentasikan secara tepat dengan angka floating point - representasi terdekat sebenarnya adalah 0,0099999998

4
Niall

Untuk sistem perbankan yang saya bantu kembangkan, saya bertanggung jawab atas bagian "bunga akrual" dari sistem. Setiap hari, kode saya menghitung berapa banyak bunga yang telah bertambah (saldo) pada saldo hari itu.

Untuk perhitungan itu, diperlukan akurasi dan kesetiaan yang ekstrem (kami menggunakan FLOAT Oracle) sehingga kami dapat merekam "seperseribu dolar" yang diperoleh.

Ketika datang untuk "mengkapitalisasi" bunga (mis. Membayar bunga kembali ke akun Anda) jumlahnya dibulatkan ke sen. Jenis data untuk saldo akun adalah dua tempat desimal. (Sebenarnya itu lebih rumit karena itu adalah sistem multi-mata uang yang bisa bekerja di banyak tempat desimal - tetapi kami selalu membulatkan ke "sen" dari mata uang itu) Ya - di sana "pecahan" kerugian dan perolehan, tetapi ketika angka-angka komputer diaktualisasikan (uang dibayarkan atau dibayar) itu selalu nilai uang NYATA.

Ini memuaskan para akuntan, auditor dan penguji.

Jadi, tanyakan kepada pelanggan Anda. Mereka akan memberi tahu Anda peraturan dan praktik perbankan/akuntansi mereka.

4
Guy

Satu-satunya alasan menggunakan Float untuk uang adalah jika Anda tidak peduli dengan jawaban yang akurat. 

4
David Singer

Hal lain yang harus Anda perhatikan dalam sistem akuntansi adalah bahwa tidak seorang pun harus memiliki akses langsung ke tabel. Ini berarti semua akses ke sistem akuntansi harus melalui procs yang disimpan. Ini mencegah penipuan bukan hanya serangan injeksi SQl. Seorang pengguna internal yang ingin melakukan penipuan seharusnya tidak memiliki kemampuan untuk secara langsung mengubah data dalam tabel database. Ini adalah kontrol internal kritis pada sistem Anda. Apakah Anda benar-benar ingin karyawan yang tidak puas pergi ke bagian belakang basis data Anda dan mulai memeriksanya? Atau menyembunyikan bahwa mereka menyetujui pengeluaran untuk vendor yang tidak sah ketika mereka tidak memiliki otoritas persetujuan? Hanya dua orang di seluruh organisasi Anda yang dapat secara langsung mengakses data dalam basis data keuangan Anda, dba Anda, dan cadangannya. Jika Anda memiliki banyak dBA, hanya dua dari mereka yang seharusnya memiliki akses ini.

Saya menyebutkan ini karena jika programmer Anda menggunakan float dalam sistem akuntansi, kemungkinan mereka benar-benar tidak terbiasa dengan gagasan kontrol internal dan tidak menganggap mereka dalam upaya pemrograman mereka.

3
HLGEM

Bahkan lebih baik daripada menggunakan desimal menggunakan hanya bilangan bulat lama (atau mungkin semacam bigint). Dengan cara ini Anda selalu memiliki akurasi setinggi mungkin, tetapi presisi dapat ditentukan. Misalnya angka 100 dapat berarti 1.00, yang diformat seperti ini:

int cents = num % 100;
int dollars = (num - cents) / 100;
printf("%d.%02d", dollars, cents);

Jika Anda ingin memiliki lebih banyak presisi, Anda dapat mengubah 100 ke nilai yang lebih besar, seperti: 10 ^ n, di mana n adalah jumlah desimal.

3
Peter Stuifzand

Dari 100 fraksi n/100, di mana n adalah bilangan alami sehingga 0 <= n dan n <100, hanya empat yang dapat direpresentasikan sebagai bilangan floating point. Lihatlah output dari program C ini:

#include <stdio.h>

int main()
{
    printf("Mapping 100 numbers between 0 and 1 ");
    printf("to their hexadecimal exponential form (HEF).\n");
    printf("Most of them do not equal their HEFs. That means ");
    printf("that their representations as floats ");
    printf("differ from their actual values.\n");
    double f = 0.01;
    int i;
    for (i = 0; i < 100; i++) {
        printf("%1.2f -> %a\n",f*i,f*i);
    }
    printf("Printing 128 'float-compatible' numbers ");
    printf("together with their HEFs for comparison.\n");
    f = 0x1p-7; // ==0.0071825
    for (i = 0; i < 0x80; i++) {
        printf("%1.7f -> %a\n",f*i,f*i);
    }
    return 0;
}
2
Lars Bohl

Anda selalu dapat menulis sesuatu seperti jenis Uang untuk .Net.

Lihatlah artikel ini: Jenis uang untuk CLR - Penulis melakukan pekerjaan yang baik menurut saya.

2
Tomer Pintel

Saya telah menggunakan jenis uang SQL untuk menyimpan nilai moneter. Baru-baru ini, saya harus bekerja dengan sejumlah sistem pembayaran online dan telah memperhatikan bahwa beberapa dari mereka menggunakan bilangan bulat untuk menyimpan nilai moneter. Dalam proyek saya saat ini dan baru saya sudah mulai menggunakan bilangan bulat dan saya cukup puas dengan solusi ini.

2
George

Anda mungkin ingin menggunakan beberapa bentuk representasi titik tetap untuk nilai mata uang. Anda juga akan ingin menyelidiki pembulatan Bankir (juga dikenal sebagai "babak setengah genap".) Ini menghindari bias yang ada dalam metode "putaran setengah ke atas" yang biasa.

1
user6931

Sudahkah Anda mempertimbangkan untuk menggunakan tipe data uang untuk menyimpan jumlah dolar?

Mengenai Con yang desimal membutuhkan satu byte lagi, saya akan mengatakan tidak peduli tentang itu. Dalam 1 juta baris, Anda hanya akan menggunakan 1 MB lebih banyak dan penyimpanan sangat murah hari ini.

1
Espo

Apa pun yang Anda lakukan, Anda harus berhati-hati dalam menyelesaikan kesalahan. Hitung menggunakan tingkat presisi yang lebih besar daripada yang Anda tampilkan.

1
1800 INFORMATION

Akuntan Anda akan ingin mengendalikan bagaimana Anda membulatkan tekad. Menggunakan float berarti Anda akan terus membulatkan, biasanya dengan pernyataan tipe FORMAT (), yang bukan cara yang Anda inginkan (gunakan lantai/langit-langit sebagai gantinya).

Anda memiliki tipe data mata uang (uang, uang kecil), yang harus digunakan daripada float atau nyata. Menyimpan desimal (12,2) akan menghilangkan pembulatan Anda, tetapi juga akan menghilangkannya selama langkah-langkah menengah - yang sebenarnya bukan yang Anda inginkan sama sekali dalam aplikasi keuangan.

0
David T. Macknet

Ini adalah artikel yang bagus untuk menjelaskan kapan menggunakan float dan desimal . Float menyimpan nilai perkiraan dan desimal menyimpan nilai yang tepat.

Singkatnya, nilai pasti seperti uang harus menggunakan desimal, dan nilai perkiraan seperti pengukuran ilmiah harus menggunakan float. 

Berikut adalah contoh menarik yang menunjukkan bahwa float dan desimal mampu kehilangan presisi. Saat menambahkan angka yang bukan bilangan bulat dan kemudian mengurangi angka float yang sama menghasilkan kehilangan presisi sementara desimal tidak:

    DECLARE @Float1 float, @Float2 float, @Float3 float, @Float4 float; 
    SET @Float1 = 54; 
    SET @Float2 = 3.1; 
    SET @Float3 = 0 + @Float1 + @Float2; 
    SELECT @Float3 - @Float1 - @Float2 AS "Should be 0";

Should be 0 
---------------------- 
1.13797860024079E-15

Saat mengalikan non integer dan membaginya dengan angka yang sama, desimal kehilangan presisi sedangkan float tidak.

DECLARE @Fixed1 decimal(8,4), @Fixed2 decimal(8,4), @Fixed3 decimal(8,4); 
SET @Fixed1 = 54; 
SET @Fixed2 = 0.03; 
SET @Fixed3 = 1 * @Fixed1 / @Fixed2; 
SELECT @Fixed3 / @Fixed1 * @Fixed2 AS "Should be 1";

Should be 1 
--------------------------------------- 
0.99999999999999900
0
BrokeMyLegBiking

Selalu gunakan Desimal. Float akan memberi Anda nilai yang tidak akurat karena masalah pembulatan.

0
Roel Vlemmings

Angka floating point dapat hanya mewakili angka yang merupakan kelipatan negatif dari basis - untuk floating point biner, tentu saja, itu dua.

Hanya ada empat pecahan desimal yang dapat diwakili secara tepat di titik mengambang biner: 0, 0,25, 0,5 dan 0,75. Segala sesuatu yang lain adalah perkiraan, dengan cara yang sama dengan 0,3333 ... adalah perkiraan untuk 1/3 dalam aritmatika desimal.

Floating point adalah pilihan yang baik untuk perhitungan di mana skala hasilnya adalah yang penting. Ini adalah pilihan yang buruk di mana Anda mencoba untuk menjadi akurat ke beberapa tempat desimal.

0
Mike Dimmick