/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:strict
uyumlu 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:precise
varsayılan olarak oluşturulmaz. Bu davranış Visual Studio 2022'de yenidir. Önceki derleyici sürümleri altında /fp:precise
varsayı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:precise
oluş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) * a
a + a
mı a * 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:precise
bir 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:strict
oluş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:fast
gö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:fast
oluşturulabilir. Derleyici, altındaki /fp:fast
temel 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:except
ve /fp:precise
etkinleştirmez. seçeneği /fp:except
ile /fp:fast
uyumlu 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:fast
ve /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 /clr
uyumlu değildir.
/Za
(ANSI uyumluluğu) seçeneği ile /fp
uyumlu 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_access
ve 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, , double
ve long double
değerleri için float
varsayı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 , _clearfp
ve _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_access
fenv_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:fast
de /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:precise
altı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:strict
altı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:strict
ve /fp:fast
altı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:fast
derlendiğ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:strict
altı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:fast
bu tür dönüştürmeler yapabilir. Örneğin, örnek işlevdeki algebraic_transformation
ifade a * b + a * c
altında /fp:fast
derlenebilira * (b + c)
. Bu tür dönüştürmeler veya /fp:strict
altı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:strict
altı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:strict
kullanı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
Projenin Özellik Sayfaları iletişim kutusunu açın. Ayrıntılar için bkz . Visual Studio'da C++ derleyicisi ve derleme özelliklerini ayarlama.
Yapılandırma Özellikleri>C/C++>Kod Oluşturma özellik sayfasını seçin.
Kayan Nokta Modeli özelliğini değiştirin.
Bu derleyici seçeneğini program üzerinden ayarlamak için
- Bkz. floatingPointModel.
Ayrıca bkz.
MSVC derleyici seçenekleri
MSVC derleyicisi komut satırı söz dizimi