Aracılığıyla paylaş


/fp (Kayan nokta davranışını belirtin)

Derleyicinin kayan nokta ifadelerini, iyileştirmelerini ve özel durumlarını nasıl işleyip işlemeyişini belirtir. Seçenekler, /fp oluşturulan kodun kayan nokta ortamının yuvarlama moduna, özel durum maskelerine ve normal olmayan davranışa değişmesine izin verip vermediğini ve kayan nokta durum denetimlerinin geçerli, doğru sonuçlar döndürip döndürmediğini belirtir. Derleyicinin kaynak işlemi ve ifade sırasını koruyan ve NaN yayma standardına uyan bir kod oluşturup oluşturmadığını denetler. Ya da bunun yerine işlemleri yeniden sıralayan veya bir araya getirebilen ve IEEE-754 standardı tarafından izin verilmeyen cebirsel dönüşümleri basitleştiren daha verimli bir kod oluşturursa.

Sözdizimi

/fp:contract
/fp:except[-]
/fp:fast
/fp:precise
/fp:strict

/fp:except[-]
/fp:fast
/fp:precise
/fp:strict

Bağımsız değişkenler

/fp:contract

seçeneği, /fp:contract ve /fp:except seçeneklerini belirttiğinizde derleyicinin kayan noktalı kasılmalar oluşturmasına /fp:precise olanak tanır. Kasılma, Fused-Multiply-Add (FMA) gibi kayan nokta işlemlerini birleştiren bir makine yönergesidir. IEEE-754 tarafından temel bir işlem olarak tanımlanan FMA, ara ürünü toplamadan önce yuvarlamaz, bu nedenle sonuç ayrı çarpma ve toplama işlemlerinden farklı olabilir. Tek bir yönerge olarak uygulandığından, ayrı yönergelerden daha hızlı olabilir. Hız, bit düzeyinde kesin sonuçlara ve ara değerin incelenememesine neden olur.

seçeneği varsayılan olarak /fp:fast seçeneğini etkinleştirir /fp:contract. seçeneği /fp:contract ile /fp:strictuyumlu değildir.

Bu /fp:contract seçenek Visual Studio 2022'de yenidir.

/fp:precise

Varsayılan olarak, derleyici davranışı kullanır /fp:precise .

altında /fp:precise, derleyici hedef makine için nesne kodu oluşturup iyileştirdiğinde kayan nokta kodunun kaynak ifade sıralama ve yuvarlama özelliklerini korur. Derleyici, ifade değerlendirmesi sırasında dört belirli noktada kaynak kodu duyarlığına yuvarlar: atamalarda, tür yayınlarında, kayan nokta bağımsız değişkenleri bir işlev çağrısına geçirildiğinde ve bir işlev çağrısı kayan nokta değeri döndürdüğünde. Ara hesaplamalar makine duyarlığında gerçekleştirilebilir. Tür yayınları, ara hesaplamaları açıkça yuvarlamada kullanılabilir.

Derleyici, dönüştürmenin bit düzeyinde özdeş bir sonuç ürettiğini garanti etmediği sürece yeniden ilişkilendirme veya dağıtım gibi kayan nokta ifadelerinde cebirsel dönüştürmeler gerçekleştirmez. Özel değerler (NaN, +infinity, -infinity, -0.0) içeren ifadeler IEEE-754 belirtimlerine göre işlenir. Örneğin, x != x NaN olup olmadığını x değerlendirirtrue. Kayan noktalı kasılmalar altında /fp:precisevarsayılan olarak oluşturulmaz. Bu davranış Visual Studio 2022'de yenidir. Önceki derleyici sürümleri altında /fp:precisevarsayılan olarak sözleşmeler oluşturabilir.

Derleyici, dönüştürmenin bit düzeyinde özdeş bir sonuç ürettiğini garanti etmediği sürece yeniden ilişkilendirme veya dağıtım gibi kayan nokta ifadelerinde cebirsel dönüştürmeler gerçekleştirmez. Özel değerler (NaN, +infinity, -infinity, -0.0) içeren ifadeler IEEE-754 belirtimlerine göre işlenir. Örneğin, x != x NaN olup olmadığını x değerlendirirtrue. Kayan noktalı kasılmalar altında /fp:preciseoluşturulabilir.

Derleyici, varsayılan kayan nokta ortamında çalıştırılması amaçlanan kodu oluşturur. Ayrıca kayan nokta ortamına çalışma zamanında erişilmiyor veya değiştirilmiyor. Diğer bir ifadeyle, kodu kabul eder: kayan nokta özel durumlarını maskelenmiş olarak bırakır, kayan nokta durum yazmaçlarını okumaz veya yazmaz ve yuvarlama modlarını değiştirmez.

Kayan nokta kodunuz kayan nokta deyimlerinizdeki işlemlerin ve ifadelerin sırasına bağlı değilse (örneğin, olarak mı 2 * a yoksa olarak (b + c) * aa + aa * b + a * c hesaplanması önemli değilse), daha hızlı ve daha verimli kod üretebilecek seçeneği göz önünde bulundurun/fp:fast. Kodunuz hem işlemlerin hem de ifadelerin sırasına bağlıysa ve kayan nokta ortamına erişiyorsa veya bunları değiştiriyorsa (örneğin, yuvarlama modlarını değiştirmek veya kayan nokta özel durumlarını yakalamak için) kullanın /fp:strict.

/fp:strict

/fp:strict gibi /fp:precisebir davranışa sahiptir, yani derleyici hedef makine için nesne kodu oluşturup iyileştirdiğinde kayan nokta kodunun kaynak sıralama ve yuvarlama özelliklerini korur ve özel değerleri işlerken standardı gözlemler. Program ayrıca çalışma zamanında kayan nokta ortamına güvenli bir şekilde erişebilir veya bunları değiştirebilir.

altında /fp:strict, derleyici programın kayan nokta özel durumlarının maskesini güvenli bir şekilde kaldırmasına, kayan nokta durum yazmaçlarını okumasına veya yazmasına ya da yuvarlama modlarını değiştirmesine olanak tanıyan kod oluşturur. İfade değerlendirmesi sırasında dört belirli noktada kaynak kodu duyarlığına yuvarlar: atamalarda, tür yayınlarında, kayan nokta bağımsız değişkenleri bir işlev çağrısına geçirildiğinde ve bir işlev çağrısı kayan nokta değeri döndürdüğünde. Ara hesaplamalar makine duyarlığında gerçekleştirilebilir. Tür yayınları, ara hesaplamaları açıkça yuvarlamada kullanılabilir. Derleyici, dönüştürmenin bit düzeyinde özdeş bir sonuç ürettiğini garanti etmediği sürece yeniden ilişkilendirme veya dağıtım gibi kayan nokta ifadelerinde cebirsel dönüştürmeler yapmaz. Özel değerler (NaN, +infinity, -infinity, -0.0) içeren ifadeler IEEE-754 belirtimlerine göre işlenir. Örneğin, x != x NaN olup olmadığını x değerlendirirtrue. Kayan noktalı kasılmalar altında /fp:strictoluşturulmaz.

/fp:strict derleyicinin özel durumları yakalamak ve programların çalışma zamanında kayan nokta ortamına erişmesine veya bunları değiştirmesine izin vermek için ek yönergeler eklemesi gerektiğinden hesaplama açısından daha /fp:precise pahalıdır. Kodunuz bu özelliği kullanmıyorsa, ancak kaynak kodu sıralama ve yuvarlama gerektiriyorsa veya özel değerleri kullanıyorsa kullanın /fp:precise. Aksi takdirde, daha hızlı ve daha küçük kodlar üretebilen kullanmayı /fp:fastgöz önünde bulundurun.

/fp:fast

seçeneği, /fp:fast kayan nokta kodunu hız ve alan için iyileştirmek üzere derleyicinin kayan nokta işlemlerini yeniden sıralamasına, birleştirmesine veya basitleştirmesine olanak tanır. Derleyici atama deyimlerinde, tür yayınlarında veya işlev çağrılarında yuvarlama işlemini atlar. İşlemleri yeniden sıralayabilir veya örneğin ilişkilendirici ve dağıtıcı yasalar kullanarak cebirsel dönüşümler yapabilir. Bu tür dönüştürmeler gözlemlenebilir şekilde farklı yuvarlama davranışına neden olsa bile kodu yeniden sıralayabilir. Bu gelişmiş iyileştirme nedeniyle, bazı kayan noktalı hesaplamaların sonucu diğer /fp seçenekler tarafından üretilenlerden farklı olabilir. Özel değerler (NaN, +sonsuzluk, -sonsuzluk, -0,0) IEEE-754 standardına göre yayılmayabilir veya kesinlikle davranış göstermeyebilir. Kayan noktalı kasılmalar altında /fp:fastoluşturulabilir. Derleyici, altındaki /fp:fasttemel mimariye bağlı olmaya devam eder ve seçeneğin kullanımıyla /arch daha fazla iyileştirme kullanılabilir.

altında /fp:fast, derleyici varsayılan kayan nokta ortamında çalıştırılması amaçlanan kodu oluşturur ve kayan nokta ortamına çalışma zamanında erişilmiyor veya değiştirilmemiş olduğunu varsayar. Diğer bir ifadeyle, kodu kabul eder: kayan nokta özel durumlarını maskelenmiş olarak bırakır, kayan nokta durum yazmaçlarını okumaz veya yazmaz ve yuvarlama modlarını değiştirmez.

/fp:fast , kayan nokta ifadelerinin katı kaynak kodu sıralamasını ve yuvarlamasını gerektirmeyen ve gibi NaNözel değerleri işlemek için standart kurallara güvenmeyen programlara yöneliktir. Kayan nokta kodunuz kaynak kodu sıralama ve yuvarlamanın korunmasını gerektiriyorsa veya özel değerlerin standart davranışına bağlıysa kullanın /fp:precise. Kodunuz yuvarlama modlarını değiştirmek, kayan nokta özel durumlarının maskesini silmek veya kayan nokta durumunu denetlemek için kayan nokta ortamına erişiyorsa veya bunları değiştirirse kullanın /fp:strict.

/fp:except

seçeneği, /fp:except maskelenmemiş kayan nokta özel durumlarının tam olarak oluştuğu noktada oluşturulmasını ve başka kayan nokta özel durumlarının tetiklenmemesini sağlamak için kod oluşturur. seçeneği varsayılan olarak /fp:strict seçeneğini etkinleştirir /fp:exceptve /fp:precise etkinleştirmez. seçeneği /fp:except ile /fp:fastuyumlu değildir. seçeneği, kullanımıyla /fp:except-açıkça devre dışı bırakılabilir.

Tek başına, /fp:except kayan nokta özel durumlarını etkinleştirmez. Ancak, programların kayan nokta özel durumlarını etkinleştirmesi gerekir. Kayan nokta özel durumlarını etkinleştirme hakkında daha fazla bilgi için bkz _controlfp. .

Açıklamalar

Aynı derleyici komut satırında birden çok /fp seçenek belirtilebilir. Aynı anda yalnızca bir /fp:strict, /fp:fastve /fp:precise seçeneği etkin olabilir. Komut satırında bu seçeneklerden birden fazlasını belirtirseniz, sonraki seçenek önceliklidir ve derleyici bir uyarı oluşturur. /fp:strict ve /fp:except seçenekleri ile /clruyumlu değildir.

/Za (ANSI uyumluluğu) seçeneği ile /fpuyumlu değildir.

Kayan nokta davranışını denetlemek için derleyici yönergelerini kullanma

Derleyici, komut satırında belirtilen kayan nokta davranışını geçersiz kılmak için üç pragma yönergesi sağlar: float_control, fenv_accessve fp_contract. Bir işlev içinde değil, işlev düzeyinde kayan nokta davranışını denetlemek için bu yönergeleri kullanabilirsiniz. Bu yönergeler doğrudan seçeneklere /fp karşılık gelmez. Bu tablo, seçeneklerin ve pragma yönergelerinin /fp birbiriyle nasıl eşlenimini gösterir. Daha fazla bilgi için tek tek seçenekler ve pragma yönergeleri belgelerine bakın.

Seçenek float_control(precise, *) float_control(except, *) fenv_access(*) fp_contract(*)
/fp:fast off off off on
/fp:precise on off off off*
/fp:strict on on on off

* Visual Studio'nun Visual Studio 2022 öncesi sürümlerinde, /fp:precise davranış varsayılan olarak şeklindedir fp_contract(on).

Seçenek float_control(precise, *) float_control(except, *) fenv_access(*) fp_contract(*)
/fp:fast off off off on
/fp:precise on off off on*
/fp:strict on on on off

* Visual Studio 2022'den başlayarak Visual Studio sürümlerinde, /fp:precise davranış varsayılan olarak şeklindedir fp_contract(off).

Varsayılan kayan nokta ortamı

Bir işlem başlatıldığında, varsayılan kayan nokta ortamı ayarlanır. Bu ortam tüm kayan nokta özel durumlarını maskeler, yuvarlama modunu en yakına (FE_TONEAREST ) yuvarlayacak şekilde ayarlar, alt normal (normal olmayan) değerleri korur, , doubleve long double değerleri için floatvarsayılan tanımlayıcı duyarlığı (mantis) kullanır ve desteklendiği durumlarda sonsuzluk denetimini varsayılan benfin moduna ayarlar.

Kayan nokta ortam erişimi ve değişikliği

Microsoft Visual C++ çalışma zamanı, kayan nokta ortamına erişmek ve bunları değiştirmek için çeşitli işlevler sağlar. Bunlar , _clearfpve _statusfp çeşitlemelerini içerir_controlfp. Kodunuz kayan nokta ortamına eriştiğinde veya ortamı değiştirdiğinde doğru program davranışını sağlamak için, fenv_access bu işlevlerin fenv_access herhangi bir etkiye sahip olması için, seçenek veya pragma kullanımıyla etkinleştirilmesi /fp:strict gerekir. Etkinleştirilmediğinde fenv_access , kayan nokta ortamına erişim veya değişiklik beklenmeyen program davranışına neden olabilir:

  • Kod, kayan nokta ortamında istenen değişikliklere saygı göstermeyebilir,

  • Kayan nokta durum kayıtları beklenen veya geçerli sonuçları bildirmeyebilir,

  • Beklenmeyen kayan nokta özel durumları oluşabilir veya beklenen kayan nokta özel durumları gerçekleşmeyebilir.

Kodunuz kayan nokta ortamına eriştiğinde veya ortamı değiştirdiğinde, etkin olmayan kodla etkinleştirilen kodu fenv_accessfenv_access birleştirirken dikkatli olmanız gerekir. Etkin olmayan kodda fenv_access derleyici, platform varsayılan kayan nokta ortamının etkin olduğunu varsayar. Ayrıca kayan nokta durumuna erişilmiyor veya değiştirilmiyor varsayılır. Denetimin etkinleştirilmemiş bir işleve fenv_access aktarılması için yerel kayan nokta ortamını kaydetmenizi ve varsayılan durumuna geri yüklemenizi öneririz. Bu örnekte pragmanın nasıl float_control ayarlanıp geri yüklenebileceği gösterilmektedir:

#pragma float_control(precise, on, push)
// Code that uses /fp:strict mode
#pragma float_control(pop)

Kayan nokta yuvarlama modları

Hem hem /fp:fastde /fp:precise altında, derleyici varsayılan kayan nokta ortamında çalıştırılması amaçlanan kodu oluşturur. Ortamın çalışma zamanında erişilmiyor veya değiştirilmiyor olduğunu varsayar. Diğer bir ifadeyle, derleyici kodun kayan nokta özel durumlarının maskesini asla kaldırmadığını, kayan nokta durum yazmaçlarını okumadığını veya yazdığını ya da yuvarlama modlarını değiştirmediğini varsayar. Ancak, bazı programların kayan nokta ortamını değiştirmesi gerekir. Örneğin, bu örnek kayan nokta yuvarlama modlarını değiştirerek kayan nokta çarpmasının hata sınırlarını hesaplar:

// fp_error_bounds.cpp
#include <iostream>
#include <limits>
using namespace std;

int main(void)
{
    float a = std::<float>::max();
    float b = -1.1;
    float cLower = 0.0;
    float cUpper = 0.0;
    unsigned int control_word = 0;
    int err = 0;

    // compute lower error bound.
    // set rounding mode to -infinity.
    err = _controlfp_s(&control_word, _RC_DOWN, _MCW_RC);
    if (err)
    {
        cout << "_controlfp_s(&control_word, _RC_DOWN, _MCW_RC) failed with error:" << err << endl;
    }  
    cLower = a * b;

    // compute upper error bound.
    // set rounding mode to +infinity.
    err = _controlfp_s(&control_word, _RC_UP, _MCW_RC);
    if (err)
    {
        cout << "_controlfp_s(&control_word, _RC_UP, _MCW_RC) failed with error:" << err << endl;
    }
    cUpper = a * b;

    // restore default rounding mode.
    err = _controlfp_s(&control_word, _CW_DEFAULT, _MCW_RC);
    if (err)
    {
        cout << "_controlfp_s(&control_word, _CW_DEFAULT, _MCW_RC) failed with error:" << err << endl;
    }
    // display error bounds.
    cout << "cLower = " << cLower << endl;
    cout << "cUpper = " << cUpper << endl;
    return 0;
}

Derleyici ve /fp:precisealtında /fp:fast varsayılan kayan nokta ortamını varsaydığından çağrısı yok saymak _controlfp_sücretsizdir. Örneğin, x86 mimarisi için hem /fp:precise hem de /O2 kullanılarak derlendiğinde sınırlar hesaplanmamıştır ve örnek program çıkışları:

cLower = -inf
cUpper = -inf

x86 mimarisi için hem /fp:strict hem de /O2 kullanılarak derlendiğinde örnek program şunları verir:

cLower = -inf
cUpper = -3.40282e+38

Kayan nokta özel değerleri

ve /fp:strictaltında/fp:precise, özel değerler içeren ifadeler (NaN, +sonsuz, -infinity, -0,0) IEEE-754 belirtimlerine göre davranır. altında /fp:fast, bu özel değerlerin davranışı IEEE-754 ile tutarsız olabilir.

Bu örnek, , /fp:strictve /fp:fastaltındaki /fp:preciseözel değerlerin farklı davranışını gösterir:

// fp_special_values.cpp
#include <stdio.h>
#include <cmath>

float gf0 = -0.0;

int main()
{
    float f1 = INFINITY;
    float f2 = NAN;
    float f3 = -INFINITY;
    bool a, b;
    float c, d, e;
    a = (f1 == f1);
    b = (f2 == f2);
    c = (f1 - f1);
    d = (f2 - f2);
    e = (gf0 / f3);
    printf("INFINITY == INFINITY : %d\n", a);
    printf("NAN == NAN           : %d\n", b);
    printf("INFINITY - INFINITY  : %f\n", c);
    printf("NAN - NAN            : %f\n", d);
    printf("std::signbit(-0.0/-INFINITY): %d\n", std::signbit(e));
    return 0;
}

veya kullanılarak /O2 /fp:precise veya /O2 /fp:strict x86 mimarisi için derlendiğinde, çıkışlar IEEE-754 belirtimi ile tutarlıdır:

INFINITY == INFINITY : 1
NAN == NAN           : 0
INFINITY - INFINITY  : -nan(ind)
NAN - NAN            : nan
std::signbit(-0.0/-INFINITY): 0

x86 mimarisi için ** kullanılarak /O2 /fp:fastderlendiğinde çıkışlar IEEE-754 ile tutarlı değildir:

INFINITY == INFINITY : 1
NAN == NAN           : 1
INFINITY - INFINITY  : 0.000000
NAN - NAN            : 0.000000
std::signbit(-0.0/-INFINITY): 0

Kayan nokta cebirsel dönüşümler

ve /fp:strictaltında/fp:precise, dönüştürmenin bit düzeyinde özdeş bir sonuç üretmesi garanti edilmediği sürece derleyici herhangi bir matematiksel dönüştürme yapmaz. Derleyici altında /fp:fastbu tür dönüştürmeler yapabilir. Örneğin, örnek işlevdeki algebraic_transformation ifade a * b + a * c altında /fp:fastderlenebilira * (b + c). Bu tür dönüştürmeler veya /fp:strictaltında /fp:precise yapılmaz ve derleyici oluşturura * b + a * c.

float algebraic_transformation (float a, float b, float c)
{
    return a * b + a * c;
}

Kayan nokta açık atama noktaları

ve /fp:strictaltında/fp:precise, derleyici ifade değerlendirmesi sırasında dört belirli noktada kaynak kodu duyarlığına yuvarlar: atamalarda, tür yayınlarında, kayan nokta bağımsız değişkenleri bir işlev çağrısına geçirildiğinde ve bir işlev çağrısı kayan nokta değeri döndürdüğünde. Tür yayınları, ara hesaplamaları açıkça yuvarlamada kullanılabilir. altında /fp:fast, derleyici kaynak kodu duyarlığını garanti etmek için bu noktalarda açık atamalar oluşturmaz. Bu örnek, farklı /fp seçenekler altındaki davranışı gösterir:

float casting(float a, float b)
{
    return 5.0*((double)(a+b));
}

veya /O2 /fp:strictkullanılarak /O2 /fp:precise derlendiğinde, x64 mimarisi için oluşturulan kodun hem tür yayınına hem de işlev dönüş noktasına açık tür atamalarının eklendiğini görebilirsiniz:

        addss    xmm0, xmm1
        cvtss2sd xmm0, xmm0
        mulsd    xmm0, QWORD PTR __real@4014000000000000
        cvtsd2ss xmm0, xmm0
        ret      0

Oluşturulan kodun altında /O2 /fp:fast tüm tür atamaları iyileştirildiğinden basitleştirilmiştir:

        addss    xmm0, xmm1
        mulss    xmm0, DWORD PTR __real@40a00000
        ret      0

Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için

  1. Projenin Özellik Sayfaları iletişim kutusunu açın. Ayrıntılar için bkz . Visual Studio'da C++ derleyicisi ve derleme özelliklerini ayarlama.

  2. Yapılandırma Özellikleri>C/C++>Kod Oluşturma özellik sayfasını seçin.

  3. Kayan Nokta Modeli özelliğini değiştirin.

Bu derleyici seçeneğini program üzerinden ayarlamak için

Ayrıca bkz.

MSVC derleyici seçenekleri
MSVC derleyicisi komut satırı söz dizimi