Makale numarası: 125056 - Son Gözden Geçirme: 24 Şubat 2005 Perşembe - Gözden geçirme: 2.1

BILGI: Duyarlığı ve doğruluğu, kayan nokta hesaplamaları

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.

Bu Sayfada

Hepsini aç | Hepsini kapa

Özet

Yuvarlama Duyarlığı hangi, birçok durumda vardır ve kayan nokta hesaplamalarında doğruluğu, Programcı için de şaşırtıcı olan sonuçlar üretmek için çalışabilirsiniz. Gelmelidir dört genel kurallar vardır:
  1. Tek ve çift duyarlıklı ilgili hesaplamasında, sonuç genellikle tek duyarlıklı artık doğru olur. Çift duyarlıklı gerekiyorsa, çift duyarlıklı belirtilen hesaplamasında sabitleri dahil olmak üzere tüm terimler emin olun.
  2. Hiçbir zaman basit bir sayısal değer bilgisayarda doğru olarak temsil edilen varsayalım. Kayan noktalı değer en kesin sınırlı bir ikili değer gösterilemeyen. Örneğin,.1.0001100110011 ise... (bunu sonsuza kadar yinelenir), ikili düzende; bu nedenle, tüm bilgisayarları içeren ikili aritmetik, kullanan bir bilgisayarda tam hassasiyeti ile gösterilemeyen.
  3. Hiçbir sonuç son ondalık yere doğru olduğu varsayılmaktadır. "True" yanıt ve sınırlı herhangi bir kayan nokta işleme birimi duyarlığını ile hesaplanabilir küçük farklılıkları her zaman vardır.
  4. Hiçbir zaman eşit veya değil eşit olup olmadıklarını görmek için iki kayan noktalı değer karşılaştırın. 3. Kural için bir corollary budur. Var olan hemen hemen her zaman geçmeden eşit olmalı sayı arasındaki küçük farklılıklar olacak. Bunun yerine, her zaman sayıları, yaklaşık olarak eşit olup olmadığını denetleyin. Diğer bir deyişle, bunlar arasındaki fark çok küçük ya da anlamsız olup olmadığını denetleyin.

Daha fazla bilgi

Genel olarak, yukarıda açıklanan kurallar, C, C++ ve Çevirici gibi tüm diller için geçerlidir. Aşağıdaki örneklerde FORTRAN PowerStation kullanma kuralları bazılarını göstermektedir. Tüm örnekleri için c yazılan son biri dışında tüm seçeneksiz FORTRAN PowerStation 32 kullanarak derlendi

Lütfen sayısal sabitlere ve kayan noktalı değer bir iç gösterim için bir açıklama için makale 36068  (http://support.microsoft.com/kb/36068/EN-US/ ) açıklaması için Microsoft FORTRAN ile sağlanan FORTRAN manual(s) bakın.

Örnek 1

Ilk örnek, iki şey gösterir:

  • FORTRAN sabitler, varsayılan olarak, tek duyarlıklı olduğunu (C sabitleri çift duyarlıklı varsayılan bilgilerdir).
  • Herhangi bir tek duyarlıklı terimleri içeren hesaplamalar tüm koşulları tek duyarlıklı olan hesaplamaları çok daha doğru değil.
Başlatıldı (tek duyarlıklı sabit) 1.1 ile sonra y tek duyarlıklı değişken olarak olarak yanlış olur.
   x = 1.100000000000000  y = 1.100000023841858
				
Bir tek duyarlıklı değer bir <a0>doğru çift duyarlıklı</a0> değeriyle çarpımının sonucu iki tek duyarlıklı değerleri çarpmadan olarak yaklaşık olarak bozuk. Her iki hesaplamaları sayıyı, binlik olarak iki çift duyarlıklı değerleri çarpmadan kadar hata var.
   true = 1.320000000000000 (multiplying 2 double precision values)
   y    = 1.320000052452087 (multiplying a double and a single)
   z    = 1.320000081062318 (multiplying 2 single precision values)
				

Örnek kod

C Compile options: none

       real*8 x,y,z
       x = 1.1D0
       y = 1.1
       print *, 'x =',x, 'y =', y
       y = 1.2 * x
       z = 1.2 * 1.1
       print *, x, y, z
       end
				

ÖRNEK 2

Örnek 2 ikinci derece denklem Denklem kullanır. Bu, hatta çift duyarlıklı hesaplamaları kusursuz değildir ve bir hesaplamanın sonucunu önce sınanacağı üzerinde küçük hataları farklı sonuçlar varsa bağımlı gösterir. Örnek 2 KAREKÖK fonksiyonu yalnızca biraz daha çok negatif girilir, ancak yine de geçersiz. Çift duyarlıklı hesaplamaları küçük hatalar varsa, sonuç olacaktır:
   Root =   -1.1500000000
				
yerine, aşağıdaki hata yeniden üretir:
Çalışma zamanı hatası M6201: MATEMATIK
-sqrt: ETKIALANı hata

Örnek kod

C Compile options: none

       real*8 a,b,c,x,y
       a=1.0D0
       b=2.3D0
       c=1.322D0
       x = b**2
       y = 4*a*c
       print *,x,y,x-y
       print "(' Root =',F16.10)",(-b+dsqrt(x-y))/(2*a)
       end
				

ÖRNEK 3

Örnek: 3 en iyi duruma getirme açık olsa bile, iyileştirme nedeniyle değerleri geçici olarak beklenenden yüksek duyarlık korunmasını ve bu iki kayan nokta değeri için eşitlik sınamak çok unwise olduğunu gösterir.

Bu örnekte, iki eşittir ve eşit değil değerlerdir. Ilk Eğer, en Z değerinin hala işlemcisi'nin yığında ve aynı duyarlığı Y olarak sahiptir. Bu nedenle, X, Y eşit değildir ve ilk iletiyi yazdırılır. Ikinci EĞER anda Z bellekten yüklenmesine ve dolayısıyla duyarlık ve X değeri ve ikinci ileti de yazdırılır.

Örnek kod

C Compile options: none

       real*8 y
       y=27.1024D0
       x=27.1024
       z=y
       if (x.ne.z) then
         print *,'X does not equal Z'
       end if
       if (x.eq.z) then
         print *,'X equals Z'
       end if
       end
				

ÖRNEK 4

Örnek kodu 4 ilk bölümü için 1.0 yakın iki sayı arasındaki olası en küçük farkın hesaplar. Bunu 1.0 bir ikili gösterimi için tek bir bit ekleyerek yapar.
   x   = 1.00000000000000000  (one bit more than 1.0)
   y   = 1.00000000000000000  (exactly 1.0)
   x-y =  .00000000000000022  (smallest possible difference)
				
FORTRAN'ın bazı sürümleri, bunları görüntülerken numaralarını yuvarlamak için devralınan sayısal imprecision nedenle açık değil. Bu nedenle, x ve y aynı görüntülendiğinde görünür.

Ikinci örnek kodu 4 bölümü 10.0 yakın 2 sayıları arasındaki olası en küçük farkın hesaplar. Yeniden bunu 10.0 bir ikili gösterimi için tek bir bit ekleyerek yapar. Sayı 10'yakınında arasındaki farkı farkı 1'yakınında büyük olduğuna dikkat edin. Bu genel ilkesine gösterir, büyük mutlak değeri çok sayıda daha hassas bir şekilde, belirli bir bit sayısı depolanabilir.
   x   = 10.00000000000000000  (one bit more than 10.0)
   y   = 10.00000000000000000  (exactly 10.0)
   x-y =   .00000000000000178
				
, Yalnızca bir bit farklı göstermek için bu numaraları bir ikili gösterimini da görüntülenir.
   x = 4024000000000001 Hex
   y = 4024000000000000 Hex
				
Örnek kodu 4 son bölümünü basit yinelenmeyen Ondalıklı değerler genellikle ikili düzende yalnızca yinelenen bir kesir temsil edilebilir olduğunu gösterir. Bu büyük/küçük harf x CCCCCCCC....(Hex) yinelenen bir faktör olarak mantis gerektiren 1.05 =. Içinde FORTRAN, "C" son basamağını "D için" en yüksek olası doğruluğu sağlamak için yukarı yuvarlanır:
   x = 3FF0CCCCCCCCCCCD (Hex representation of 1.05D0)
				
bile yuvarlama sonra sonucu tam doğru değil. Ilk rakam kaldırarak görebiliriz en az önemli basamak sonra bazı hata var.
   x-1 = .05000000000000004
				

Örnek kod

C Compile options: none

       IMPLICIT real*8 (A-Z)
       integer*4 i(2)
       real*8 x,y
       equivalence (i(1),x)

       x=1.
       y=x
       i(1)=i(1)+1
       print "(1x,'x  =',F20.17,'  y=',f20.17)", x,y
       print "(1x,'x-y=',F20.17)", x-y
       print *

       x=10.
       y=x
       i(1)=i(1)+1
       print "(1x,'x  =',F20.17,'  y=',f20.17)", x,y
       print "(1x,'x-y=',F20.17)", x-y
       print *
       print "(1x,'x  =',Z16,' Hex  y=',Z16,' Hex')", x,y
       print *

       x=1.05D0
       print "(1x,'x  =',F20.17)", x
       print "(1x,'x  =',Z16,' Hex')", x
       x=x-1
       print "(1x,'x-1=',F20.17)", x
       print *

       end
				

ÖRNEK: 5

C, varsayılan olarak çift kayan sabit sayılardır. "F", "89.95f" olduğu gibi bir kayan nokta değeri belirtmek için kullanın.
   /* Compile options needed: none
   */ 

   #include <stdio.h>

   void main()
   {
      float floatvar;
      double doublevar;

   /* Print double constant. */ 
      printf("89.95 = %f\n", 89.95);      // 89.95 = 89.950000

   /* Printf float constant */ 
      printf("89.95 = %f\n", 89.95F);     // 89.95 = 89.949997

   /*** Use double constant. ***/ 
      floatvar = 89.95;
      doublevar = 89.95;

      printf("89.95 = %f\n", floatvar);   // 89.95 = 89.949997
      printf("89.95 = %lf\n", doublevar); // 89.95 = 89.950000

   /*** Use float constant. ***/ 
      floatvar = 89.95f;
      doublevar = 89.95f;

      printf("89.95 = %f\n", floatvar);   // 89.95 = 89.949997
      printf("89.95 = %lf\n", doublevar); // 89.95 = 89.949997
   }
				

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft FORTRAN PowerStation 1.0 Standard Edition
  • Microsoft Fortran PowerStation 1.0a for MS-DOS
  • Microsoft FORTRAN PowerStation 32
  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 1.5 Professional Edition
  • Microsoft Visual C++ 1.51
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
Anahtar Kelimeler: 
kbmt kbcode kbinfo kblangc kblangfortran KB125056 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:125056  (http://support.microsoft.com/kb/125056/en-us/ )