← Blog

Para alanlarını float'ta tutmayın

23 Eylül 2026·2 dakikayazılımveritabanıpara

Finansal bir sistemde en pahalı hatalar büyük hatalar değil, bir kuruşluk farklardır. Bir raporda toplamlar tutmaz, bir faturada KDV bir kuruş kayar, bir ay sonu mutabakatı saatler sürer. Bu farkların çoğunun kaynağı aynıdır: parayı kayan noktalı sayı (float) olarak saklamak.

0,1 + 0,2 neden 0,3 etmez?

0.1 + 0.2;              // 0.30000000000000004
1.1 * 3;                // 3.3000000000000003
(0.07 * 100) === 7;     // false

number tipi (IEEE 754 double) sayıları ikili tabanda saklar. 0,1 ikili tabanda tam olarak ifade edilemez; tıpkı 1/3'ün onluk tabanda 0,333... diye sonsuza gitmesi gibi. Tek bir işlemde fark görünmez, ama binlerce satırı toplayan bir raporda birikir.

Para için iki güvenli yol

1. Tam sayı olarak en küçük birim. Tutarları kuruş cinsinden tam sayı olarak saklarsınız: 12,50 TL yerine 1250. Toplama ve karşılaştırma kesin olur; yalnızca gösterirken 100'e bölersiniz.

2. Ondalık (Decimal) tip. Veritabanında DECIMAL(18,4) gibi sabit hassasiyetli bir tip, uygulamada ise bir decimal kütüphanesi kullanırsınız. Faiz ve kur hesaplarında ara sonuçlar kuruştan daha hassas olabildiği için dört ondalık hane, yuvarlamayı en sona bırakma imkânı verir.

import { Decimal } from "decimal.js";

const tutar = new Decimal("12500.50");
const kdv = tutar.mul("0.20").toDecimalPlaces(2, Decimal.ROUND_HALF_UP);
const toplam = tutar.plus(kdv);         // kesin

Yuvarlama ne zaman yapılmalı?

Yuvarlama bir iş kuralıdır, teknik bir detay değil. Taksit hesabında kuruş farkı ilk taksite mi son taksite mi yazılacak, KDV satır bazında mı fatura toplamında mı hesaplanacak: bu kararlar yazılı olmalı ve kodda tek bir yerde uygulanmalı. En sık hata, her fonksiyonun kendi bildiği gibi yuvarlamasıdır.

Migrasyonun sessiz tuzakları

Çalışan bir sistemde float alanları decimal'e taşımak, iBERRY'de yaptığım en dikkat isteyen işlerden biriydi. Öğrendiklerim:

  • Önce veriyi ölçün. Mevcut float değerlerin kaçının iki ondalıktan fazla hane taşıdığını sayın; bu, geçmişte biriken hatanın boyutunu gösterir.
  • Dönüşümde yuvarlama kuralını açıkça seçin. CAST işleminin varsayılan davranışına güvenmeyin.
  • API sınırını unutmayın. Veritabanı decimal olsa bile JSON'da sayı olarak dönen bir tutar, istemcide yeniden float'a dönüşür. Tutarları API'de string olarak taşımak bu sızıntıyı kapatır.
  • Toplamları eski ve yeni yöntemle karşılaştırın. Migrasyon sonrası aylık toplamların kuruşu kuruşuna tutması, en iyi kabul testidir.

Para alanları için karar bir kez verilir ve her yerde aynı uygulanır: veritabanı tipi, uygulama tipi, API formatı ve yuvarlama kuralı. Bu kararı bir mimari karar kaydı (ADR) olarak yazmak, ekibe katılan herkesin aynı kuralı uygulamasını sağlar.

Kredi kartı faizi gibi gerçek bir hesapta bu kuralların nasıl uygulandığını, bu sitedeki hesaplama araçlarında görebilirsiniz.