sinyalNaN bana "değerleri eksik." ile devam etmek istemiyorum durumlarda kayan nokta özel " /> sinyalNaN bana "değerleri eksik." ile devam etmek istemiyorum durumlarda kayan nokta özel " />
SORU
11 ŞUBAT 2010, PERŞEMBE


NaN sinyal daha yararlı olur?

Son zamanlarda IEEE 754 ve X 87 mimarisi hakkında biraz okuma yaptım. "Bazı sayısal hesaplama kod üzerinde çalışıyorum, ve bunu kullanarak umuyordum . değer kayıp olarak NaN kullanarak düşünüyordum ^em>sinyalNaN bana "değerleri eksik." ile devam etmek istemiyorum durumlarda kayan nokta özel durumu yakalamak için izin verecek Tersine, kullanırdımsessizİzin NaN "değeri eksik" için bir hesaplama yoluyla yaymak. Ancak, NaNs sinyal düşünürdüm onları üzerinde var olan çok sınırlı belgelere dayalı olarak çalışmıyor.

Burada olduğunu biliyorum, ne bir özeti (bu x 87 ve VC kullanarak ):

  • (IEEE "geçersiz" hariç) x 87 davranışını denetler NaNs karşılaşıyor . ne zaman _EM_İNVALİD
  • Eğer _EM_İNVALİD (özel durum devre dışı) maskeli ise, hiçbir özel durum oluşturulur ve operasyon sessiz NaN dönebilirsiniz. Bir işlem sinyal NaN içerendeğilbir özel durum neden, ama sessiz NaN dönüştürülecektir.
  • Eğer _EM_İNVALİD maskesiz (özel durum Etkin) ise, geçersiz bir işlem (örneğin, Karekök(-1)) geçersiz bir özel durum oluşturuldu neden olur.
  • Bu x 87aslaNaN sinyal üretir.
  • Eğer _EM_İNVALİD maskesizherhangi birsinyal bir NaN (hatta bununla ilgili bir değişken başlatma) atılan geçersiz bir özel durum neden olur.

Standart Kütüphane NaN değerleri erişmek için bir yol sağlar:

std::numeric_limits<double>::signaling_NaN();

ve

std::numeric_limits<double>::quiet_NaN();

Sorun hiçbir şekilde faydası yoktur sinyal NaN görüyorum. Eğer _EM_İNVALİD maskeli ise sessiz NaN tam olarak aynı şekilde hareket eder. Yok NaN başka NaN karşılaştırılabilir olduğu, mantıksal fark yoktur.

_EM_İNVALİDdeğilmaskeli (özel durum etkin), sonra bir tane bile bir sinyal NaN ile bir değişkeni başlatmak: Bu bir istisna atar çünkü double dVal = std::numeric_limits<double>::signaling_NaN(); (sinyal NaN değeri bellek adresine saklamak için x 87 bir kayıt içine yüklenir).

Benim yaptığım gibi aşağıdaki düşünebilirsiniz:

  1. Maske _EM_İNVALİD.
  2. NaN sinyal ile değişken başlatılamadı.
  3. Unmask_EM_İNVALİD.

Ancak, adım 2 sinyal NaN sessiz bir NaN dönüştürülecek neden olur, bundan sonraki kullanırdeğilistisnalar atılmasına neden! Böylece kendini korumak için?!

Sinyal bir NaN için herhangi bir yarar ya da bir amaç var mı? Orijinal niyet bir bellek ile başlatmak için oldu unitialized bir kayan nokta değeri kullanın yakalanmış olabileceğini anlıyorum.

Eğer birisi burada ben bir şey eksik olmadığını söyleyebilir misiniz?


DÜZENLEME:

Yapmak için umduğu daha fazla göstermek için, işte bir örnek:

Veri vektörü (çiftler) üzerinde matematiksel işlemleri gerçekleştirmek düşünün. İçin bazı işlemler, istiyorum izin vektörü içeren bir "eksik DEĞER" (gibi bu karşılık gelen bir elektronik tablo sütun, örneğin, bazı hücreleri yok bir değer, ama onların varlığı önemli). Bazı işlemler için, Evetdeğilvektör "eksik değer." bir içerir izin vermek istiyor Belki de "değer eksik" -- belki de farklı bir çalışma (böylece bu geçersiz bir devlet değildir) gerçekleştirme. set içinde mevcut ise eylem farklı bir ders almak istiyorum

Bu orijinal kod şöyle görünecektir

const double MISSING_VALUE = 1.3579246e123;
using std::vector;

vector<double> missingAllowed(1000000, MISSING_VALUE);
vector<double> missingNotAllowed(1000000, MISSING_VALUE);

// ... populate missingAllowed and missingNotAllowed with (user) data...

for (vector<double>::iterator it = missingAllowed.begin(); it != missingAllowed.end();   it) {
    if (*it != MISSING_VALUE) *it = sqrt(*it); // sqrt() could be any operation
}

for (vector<double>::iterator it = missingNotAllowed.begin(); it != missingNotAllowed.end();   it) {
    if (*it != MISSING_VALUE) *it = sqrt(*it);
    else *it = 0;
}

Değer" gerçekleştirilmelidir . "eksik denetle unutmayın ^strong>her döngü tekrarında. Olsa anlıyorum çoğu durumda, sqrt fonksiyon (ya da başka herhangi bir matematiksel işlem) muhtemelen gölgede bu onay var olmadığı durumlarda ameliyat en az bir (belki de sadece bir katkı) ve kontrol pahalıya mal olur. Aslında söz "değeri eksik bir hesaplama yasal olarak bu değeri zor olabilir rağmen) geldiğinde" oyun dışı yasal giriş bir değer alır ve hatalar neden olabilir. Ayrıca teknik olarak doğru, kullanıcı giriş verileri bu değere karşı kontrol edilmeli ve uygun bir eylem alınmalıdır. Bu çözüm, daha kaba ve daha az-daha-optimal buluyorum performans-bilge. Bu performans kritik kod ve kesinlikle paralel yapılarının lüks veya bazı tür veri öğesi nesneleri yok.

NaN sürümü bu gibi görünecektir:

using std::vector;

vector<double> missingAllowed(1000000, std::numeric_limits<double>::quiet_NaN());
vector<double> missingNotAllowed(1000000, std::numeric_limits<double>::signaling_NaN());

// ... populate missingAllowed and missingNotAllowed with (user) data...

for (vector<double>::iterator it = missingAllowed.begin(); it != missingAllowed.end();   it) {
    *it = sqrt(*it); // if *it == QNaN then sqrt(*it) == QNaN
}

for (vector<double>::iterator it = missingNotAllowed.begin(); it != missingNotAllowed.end();   it) {
    try {
        *it = sqrt(*it);
    } catch (FPInvalidException&) { // assuming _seh_translator set up
        *it = 0;
    }
}

Şimdi açık kontrol ortadan kalkar ve performans Gelişmiş olmalı. Bu DEĞERLERİ kaydeder dokunmadan vektör başlatmak miyim diye çalışmaya devam eder

Ayrıca, NaN için kendine saygısı olan sqrt uygulama herhangi bir çek hayal ediyorum ve hemen döner NaN.

CEVAP
11 ŞUBAT 2010, PERŞEMBE


Anladığım kadarıyla, NaN sinyal amacı veri yapıları, ama tabii yapmaktırçalışma zamanıbaşlatma C çalışır riski olan NaN yüklü bir şamandıra kayıt parçası olarak başlatma, böylece tetikleme sinyali çünkü derleyici değil farkında olan bu araç için değer gerekiyor kopyalanacak kullanarak bir tamsayı kayıt.

Olabilir bir sinyal NaN static değeri başlatılamıyor diye umut ediyorum, ama bu bile derleyici tarafından bazı özel işlem sessiz bir NaN için çevrilmesini önlemek için gerektirir. Belki döküm sihirli bir bit kayan nokta değeri olarak tedavi başlatma sırasında önlemek için kullanabilirsiniz.

Eğer KANAMAYLA yazılı olsaydı, bu bir sorun olmazdı. ama özellikle C, C ve NaN ile bir değişkeni başlatmak için tür sistemi yıkmak gerekir bence. memcpy kullanmanızı öneririm.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EmperorTigerstar

    EmperorTiger

    14 EYLÜL 2009
  • Philip DeFranco

    Philip DeFra

    16 EYLÜL 2006
  • thenewboston

    thenewboston

    4 ŞUBAT 2008