yuvarlama

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

yuvarlama

Mesaj gönderen y.kulac »

s.a.
öncelikle ytl ve yuvarlama ilel ilgili forumumuzda çok düküman buldum ve hepsini inceledim.
ama sorunumu halledemedim.
firbird veritanbanı ve ibx bilşenlerini kullanıyorum.
veritabanında kullandığım alan float. hesaplama işlemini direk value üzerinden yaptırıyorum. displayformat özelliğinide ##0.00 olarak ayarladım

Kod: Tümünü seç

ibdataset1tabanaylık.value:= ibtable1tabanaylık.value*1000;
herşey normal sonuç 50,1252555 gibi çıkıyor. virgülden sonraki 3.sayı 5 olduğu için
normal olarak sonuç 50,12 oluyor. ama program gereği virgülden sonraki
3. sayı 5 ve üzeri ise 2.sayı bir üste yuvarlanmak zorunda 4 ve altı ise aşağı yuvarlanmak zorunda.
yani 50,125 = 50,13 75,245 = 75,25 olmalı
soru biraz uzun oldu kusura bakmayın.
neler önerirsiniz.
iyi çalışmalar.
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Kod: Tümünü seç

uses Math;
...
...
...
...
initialization
   SetRoundMode( .. ); //   rmNearest, rmDown, rmUp, rmTruncate
end.
Unit'ine şekildeki gibi initialization bölümü ekleyip rmNearest... vs. parametrelerini tek tek dener misin?

Bir de yuvarlama işlemini sen nasıl yapıyorsun? 1000 ile neden çarptın?

bkz. RoundTo function.
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

1000 ile çarpımın yuvarlama ile ilgisi yok.o tabanaylık hesaplanmasına kullanılıyor. ayrıca ben yuvarlama yapmıyorum. ama yapmam gerek. . aryıca "rmNearest... vs. parametrelerini" anlamadım. açıklarsanız sevinirim.
iyi çalışmalar.
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

rmNearest en yakın değere, rmUp yukarı rmDown aşağı yuvarlar. Programında bir dene bu parametreleri. Mesela rmUp yap.
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

hocam maalesef olmadı round fonsiyonu en yakın tam sayıya yuvarlama yapıyor. ama benim alanlar float tipinde.
kolay gelsin
t-hex
Kıdemli Üye
Mesajlar: 531
Kayıt: 18 Mar 2005 02:45
Konum: İstanbul/Antalya
İletişim:

Mesaj gönderen t-hex »

Merhaba,
O zaman sizde yuvarlatmadan önce 0.001 ekletin sayıya, o zaman istediğiniz olur. Nede olsa sizin için gerekli olan ondalık sadece 2 basamak.
highmemo

Mesaj gönderen highmemo »

Selam,

sana elimdeki fonksiyonu vereyim.

Kod: Tümünü seç

function myFixPoint(Value: Double; DecCount: Integer): Double ; 
begin
 Result := StrToFloat( Format('%.*f', [DecCount, StrToFloat(FloatToStr(Value))]) );
end;
Sakın şaşırma :
"StrToFloat(FloatToStr " böyle bir yapı kullanmamın sebebi
örneğin programda 24 diye gördüğünüz sayı aslında 23.9999 vs gidiyor.. Bu konuyu bazı arkadaşlarımız biliyor. Eğer bu şekilde kullanmazsam çok ender zamanlarda ondalıklarda hata oluşturuyor.. Şimdi örnek veremiyorum ama işini Çözer..

Kullanım Örneği
myFixPoint( IBDatasetTUTAR.asFloat * 1000, 2);
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

teşekkür ederim arkadaşlar.

sorunu halletim. t-hex kardeşimin yolunu uyguladım. sonuca 0.001 ekledim
diğer arkadaşlara da teşekkür ederim.
aslında bazı sorunlar o kadar basit ki ama insanın aklına gelmiyor.
herkese iyi çalışmalar.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Sonuca 0.001 eklemek hatalı bir sonuca götürebilir seni.
Ben şöyle bir kod yazmıştım tl'yi ytl'ye çevirirken

Kod: Tümünü seç

Edit2.Text:=FloatToStrF((StrToFloat(Edit1.Text')/1000000),ffNumber,30,2);
Hiç bir problem olmamıştı.
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
t-hex
Kıdemli Üye
Mesajlar: 531
Kayıt: 18 Mar 2005 02:45
Konum: İstanbul/Antalya
İletişim:

Mesaj gönderen t-hex »

Merhaba,
sonuca 0.001 eklemek sadece 2 haneli küsurat gerektirdiğinde yanlış sonuca götürmüyor. 3. hanenin 9 olması durumda zaten bir üste tamamlanmış oluyor, 3. hanenin 0 olması durumda da arkadaşın yaşadığı sorun ortadan kalkıyor.

Tabi bu sadece pratik bir çözüm, her şey yapılması gerektiği gibi yapılmalı
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

3. hanenin 4 olması durumunda hataya götürür bu sonuç.

Kod: Tümünü seç

3.234=3.23
3.234+0.001=3.235=3.24<>3.23
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Problemin kaynağı ve sorunun çözümü için bir link.

http://www.festra.com/eng/tip-rounding.htm

Özetle olay şu. Delphi ta Borland Pascal zamanından gelen bir yuvarlama algoritması kullanmakta. Buna bankers rounding algoritması diyorlar.

Bu algoritma şöyle çalışıyor:

- Tam sayı kısmı tek sayı ise ve ondalıklı kısım 0.5 ise bir üst tam sayıya yuvarlıyor. (Bu bizim istediğimiz)

- Tam sayı kısmı çift ve ondalıklı kısım 0.5 ise aşağıya yuvarlıyor. (İstenmeyen)

Bu bir hata falan değil. Algoritmanın yapısından kaynaklanıyor.

Gönderdiğim SetRoundMode func'u ile bunu istediğimiz hale getirmek aslında mümkün. Arkadaşınki nasıl gelmemiş anlamadım.
Kullanıcı avatarı
y.kulac
Üye
Mesajlar: 276
Kayıt: 08 Kas 2003 12:03
Konum: serdivan/sakarya

Mesaj gönderen y.kulac »

arkadaşlar
yuvarlama yapmadan dahi 12.255 sonucu zaten 12.25 oluyor (displayformat özelliğini ###,##0.00 yapınca)
ama memur maaşı hazırlanırken muhasebe müdürlüğünün talimatı gereği kuruşlu hanelerde virgülden sonraki 3. hane 5 ve üzeri ise 2.hane yukarı, 4 ten aşağı ise aşağı yuvarlanması gerekiyor. bu istisnai bir durum.
coderlord kardeşimin verdiği linkteki fonsiyonu şu şekilde değiştirdim

Kod: Tümünü seç

function RoundCorrect(R: Real): currency;
begin
  Result:= trunc(R);       // extract the integer part 
  if Frac(R) >= 0.005 then   // if fractional part >= 0.5 then...
    Result:= Result + 0.001;   // ...add 1
end;
ama sonuç 25.245 = 25.00 oluyor.
hayırlı işler kolay gelsin.
oguzozturk74
Kıdemli Üye
Mesajlar: 574
Kayıt: 01 Şub 2004 12:29
Konum: Erdemli - MERSİN

Mesaj gönderen oguzozturk74 »

Fahrettin Abi demiş ki :
------------------------------------------

Aslında round fonksiyonu doğru çalışıyor. Fakat aldığımız matematik eğitimi dolayısıyla Round fonksiyonunun çalışma mantığını yanlış tahmin ediyoruz...

Şöyle ki Round fonksiyonu normalde en yakın tam sayıya yuvarlama yapar fakat eğer yuvarlayacağınız rakam tam olarak ortada ise yani 2.5 3.5 gibi rakamlar ise o zaman en yakın çift rakama yuvarlama yapmaktadir.

Yani
round(2.5)=2
round(3.5)=4
sonuçları gayet normaldir. Sorun hepimizin başına gelen bu fonksiyonun çalışma şeklini yanlış tahmin etmemizdir. Helpten baktığınızda şu cümleyi görmektesiniz zaten.
X is a real-type expression. Round returns an Int64 value that is the value of X rounded to the nearest whole number. If X is exactly halfway between two whole numbers, the result is always the even number.

Peki çözüm ne derseniz de ya Round fonksiyonunun bu maktığını bilerek kullanın ya da 2.5 yuvarlanınca 3 olsun diyorsaniz. RoundX isimli su fonksiyonu tanimlyip kullanın.

Kod: Tümünü seç

function RoundX( x : Extended ) : Extended; 
var 
  Rint, Rdec : Extended; 
begin 
  Rint := int(x); 
  Rdec := x - Rint ; 
  If Rdec >= 0.5 then 
    Result := Rint + 1 
  else 
    Result := Rint; 
end; 
Kullanıcı avatarı
fahrettin
Admin
Mesajlar: 2619
Kayıt: 11 Haz 2003 10:38
Konum: İstanbul
İletişim:

Mesaj gönderen fahrettin »

Evet demiştim hakikaten.... :)
* http://www.fahrettin.org Manzara Fotoğraflarım... :)
* http://delphiturkiye.gunduz.info Seminerler... ;)
* http://www.hakmar.com.tr Kalite bir haktır... 8)
Cevapla