2011-03-04 14 views
18

sonucunun 87.29 olmasını bekledim. Ben de SimpleRoundTo denedim, ancak aynı sonucu üretir. ms-help: yardım olarakNiçin RoundTo (87.285, -2) => 87.28

aynı zamanda bir "garip" bir örnek vardır //embarcadero.rs2010/vcl/Math.RoundTo.html

RoundTo(1.235, -2) => 1.24 
RoundTo(1.245, -2) => 1.24 //??? 

anybody almak gerekir işlev hangi biliyor mu 87.29 sonucu? Yani: Eğer son rakam> = 5 yuvarlanırsa, < 5 yuvarlanırsa. Okulda öğretildiği gibi :)

Delphi2010 ve SetRoundMode(rmNearest)'u kullanıyorum. Ayrıca rmTruncate ile denedim. 87.285 değeri, double değişkeninde saklanır.

Ayrıca garip:

SimpleRoundTo(87.285, -2) => 87.29 

ama

x := 87.285; //double 
SimpleRoundTo(x, -2) => 87.28 
+3

Google "Bankacılar Yuvarlaması" –

+2

Aşağıdaki David ve Rob tarafından tartışıldığı gibi, yukarıdaki yorum ilk başta göründüğü kadar büyük değildir. –

cevap

19

87,285 tam belirtilemeyeceği ve en yakın çift biraz daha küçüktür.

Kayan noktadaki klasik başvuru What Every Computer Scientist Should Know About Floating- Point Arithmetic'dur.

Para birimi tabanlı hesaplamalar için, gerçekten de bu ise, temel 2 kayan nokta yerine 10 temel tür bir taban kullanmalısınız. Delphi'de Currency anlamına gelir.

+3

+1. Yuvarlama genellikle sadece para ile uğraşırken kritiktir ve para için 'Para Birimi'ni kullanmalıyız. Para birimi bu sayıyı temsil edebilir ve yuvarlama düzgün bir şekilde tamamlar. –

+0

İnsanları bu makaleye her zaman işaret ediyor gibi görünüyorum. İnsanlar, kayan nokta sayılarının gerçek yeteneklerinin ötesinde yetenekleri olduğunu düşünmektedir. Üçte birini temsil etme yeteneği gibi. Yuvarlanan bankacılar da pek çok insanı şaşırtıyor. –

+0

Para birimi her zaman bir temel 2 değeridir, ancak bir tamsayı değeridir (FPU, IIRC üzerinden yönetilse de), otomatik olarak dört ondalıklığa (sabit) ölçeklendirilir. İkili kodlanmış ondalık, TBCD kullanılarak uygulanır. Varyantları kullanarak kolayca manipüle edilebilir (bkz. VarFMTBCDCreate). –

25

Tam değeri 87.285, Delphi'de kayan nokta değeri olarak gösterilemez. A page on my Web site, Genişletilmiş Çift ve Tek olarak bu değeri gerçekten ne olduğunu gösterir:

 
87.285 = + 87.28500 00000 00000 00333 06690 73875 46962 12708 95004 27246 09375 
87.285 = + 87.28499 99999 99996 58939 48683 51519 10781 86035 15625 
87.285 = + 87.28500 36621 09375 

Varsayılan olarak, Delphi kayan nokta değişmezleri tipi Extended var ve gördüğünüz gibi, senin numarasının Genişletilmiş versiyonu hafifçe olduğunu 87.285'den daha yüksek, bu yüzden en yakın yere yuvarlamanın doğru olacağı doğrudur. Ama bir Double olarak, gerçek sayı biraz daha düşük. Bu nedenle, RoundTo numaralı telefonu aramadan önce numarayı bir Double değişkeninde açıkça saklarsanız, beklediğiniz numarayı alırsınız. Delphi kayan nokta türlerinin her biri için bu işlevin aşırı yükleri vardır.

+2

+1 Bu sayfayı web sitenizde seviyorum! Tüm bu sorulara otomatik cevaplar! –

+0

+1 Bu harika sayfa, [Good Delphi Blogs] 'a (http://stackoverflow.com/questions/2975586/good-delphi-blogs) neden ilgi duyduğumun ana nedeni oldu! –

İlgili konular