Sdílet prostřednictvím


_controlfp_s

Získá a nastaví řídicí slovo s plovoucí desetinou čárkou. Tato verze _control87, _controlfp__control87_2má vylepšení zabezpečení, jak je popsáno v funkcích zabezpečení v CRT.

Syntaxe

errno_t _controlfp_s(
    unsigned int *currentControl,
    unsigned int newControl,
    unsigned int mask
);

Parametry

currentControl
Aktuální bitová hodnota ovládacího prvku.

newControl
Nové bitové hodnoty ovládacího prvku.

mask
Maska pro nové bity ovládacích prvků, které se mají nastavit.

Vrácená hodnota

Nula v případě úspěchu nebo errno kód chyby hodnoty.

Poznámky

Funkce _controlfp_s je nezávislá na platformě a bezpečnější verze _control87, která získá řídicí slovo s plovoucí desetinou čárkou do adresy, která je uložena currentControl a nastaví ji pomocí newControl. Bity v hodnotách označují stav ovládacího prvku s plovoucí desetinou čárkou. Stav ovládacího prvku s plovoucí desetinnou čárkou umožňuje programu změnit režim přesnosti, zaokrouhlení a nekonečna v závislosti na platformě. Můžete také použít _controlfp_s k maskování nebo odmaskování výjimek s plovoucí desetinou čárkou.

Pokud je hodnota mask rovna 0, _controlfp_s získá řídicí slovo s plovoucí desetinou čárkou a uloží načtenou hodnotu do currentControl.

Pokud mask je nenulová, je nastavena nová hodnota ovládacího prvku: Pro libovolný bit, který je nastaven (tj. roven 1) v mask, odpovídající bit se new použije k aktualizaci ovládacího prvku slovo. Jinými slovy, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask)) kde fpcntrl je řídicí slovo s plovoucí desetinou čárkou. V tomto scénáři currentControl je nastavena na hodnotu po dokončení změny. Nejedná se o starou bitovou hodnotu ovládacího prvku.

Poznámka

Ve výchozím nastavení maskují knihovny za běhu všechny výjimky s plovoucí desetinou čárkou.

_controlfp_s je téměř identický s _control87 funkcí na platformách Intel (x86), x64 a ARM. Pokud cílíte na platformy x86, x64 nebo ARM, můžete použít _control87 nebo _controlfp_s.

Rozdíl mezi _control87 a _controlfp_s je v tom, jak pracují s denormálními hodnotami. U platforem _control87 Intel (x86), x64 a ARM můžete nastavit a vymazat masku DENORMAL OPERAND výjimky. _controlfp_s neupravuje masku DENORMAL OPERAND výjimky. Tento příklad ukazuje rozdíl:

_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call.
unsigned int current_word = 0;
_controlfp_s( &current_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.

Možné hodnoty pro konstantu masky (mask) a nové hodnoty ovládacího prvku (newControl) jsou uvedeny v následující šestnáctkové tabulce Hodnot. Jako argumenty těchto funkcí používejte přenosné konstanty uvedené níže (_MCW_EM_EM_INVALIDatd.) místo explicitního zadávání šestnáctkových hodnot.

Platformy odvozené od Intelu (x86) podporují DENORMAL vstupní a výstupní hodnoty hardwaru. Chování x86 je zachování DENORMAL hodnot. Platforma ARM a platformy x64, které mají podporu SSE2, umožňují DENORMAL vyprázdnění operandů a výsledků nebo vynucení nuly. Funkce _controlfp_sa _control87 , _controlfpposkytují masku pro změnu tohoto chování. Následující příklad ukazuje použití této masky:

unsigned int current_word = 0;
_controlfp_s(&current_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(&current_word, _DN_FLUSH, _MCW_DN);
// Denormal values flushed to zero by hardware on ARM platforms
// and x64 processors with SSE2 support. Ignored on other x86 platforms.

Na platformách ARM se _controlfp_s tato funkce vztahuje na registr FPSCR. V architekturách x64 je ovlivněno pouze ovládací slovo SSE2 uložené v registru MXCSR. Na platformách _controlfp_s Intel (x86) ovlivňuje řídicí slova pro platformu x87 i SSE2, pokud jsou k dispozici. Tato dvě řídicí slova mohou být vzájemně nekonzistentní (například kvůli předchozímu volání __control87_2), pokud jsou mezi těmito dvěma ovládacími slovy nekonzistence, _controlfp_s nastaví EM_AMBIGUOUS příznak v currentControl. Jedná se o upozornění, že vrácené slovo ovládacího prvku nemusí přesně představovat stav obou ovládacích slov s plovoucí desetinou čárkou.

V architekturách ARM a x64 není změna režimu nekonečna nebo přesnost s plovoucí desetinnou čárkou podporována. Pokud se maska ovládacího prvku přesnosti používá na platformě x64, funkce vyvolá kontrolní výraz a vyvolá se neplatná obslužná rutina parametrů, jak je popsáno v ověření parametru.

Pokud maska není správně nastavená, tato funkce vygeneruje neplatnou výjimku parametru, jak je popsáno v ověření parametru. Pokud je spuštění povoleno pokračovat, tato funkce vrátí EINVAL a nastaví errno hodnotu EINVAL.

Tato funkce je ignorována při použití /clr (Common Language Runtime Compilation) ke kompilaci, protože modul CLR (Common Language Runtime) podporuje pouze výchozí přesnost s plovoucí desetinnou čárkou.

Ve výchozím nastavení je globální stav této funkce vymezen na aplikaci. Chcete-li toto chování změnit, přečtěte si téma Globální stav v CRT.

Maskování konstant a hodnot

Vymazáním masky _MCW_EM se nastaví výjimka, která umožňuje výjimku hardwaru. Nastavení skryje výjimku. _EM_UNDERFLOW Pokud dojde k nějaké nebo _EM_OVERFLOW k chybě, není vyvolán žádná výjimka hardwaru, dokud se nespustí další instrukce s plovoucí desetinnou čárkou. Chcete-li vygenerovat výjimku hardwaru ihned po _EM_UNDERFLOW nebo _EM_OVERFLOW, zavolejte FWAIT MASM instrukce.

Maska Šestnáctkové hodnoty Konstanta Šestnáctkové hodnoty
_MCW_DN (Denormální řízení) 0x03000000 _DN_SAVE

_DN_FLUSH
0x00000000

0x01000000
_MCW_EM (Maska výjimky přerušení) 0x0008001F _EM_INVALID

_EM_DENORMAL

_EM_ZERODIVIDE

_EM_OVERFLOW

_EM_UNDERFLOW

_EM_INEXACT
0x00000010

0x00080000

0x00000008

0x00000004

0x00000002

0x00000001
_MCW_IC (Ovládací prvek nekonečna)

(Nepodporuje se na platformách ARM nebo x64.)
0x00040000 _IC_AFFINE

_IC_PROJECTIVE
0x00040000

0x00000000
_MCW_RC (Ovládací prvek zaokrouhlování) 0x00000300 _RC_CHOP

_RC_UP

_RC_DOWN

_RC_NEAR
0x00000300

0x00000200

0x00000100

0x00000000
_MCW_PC (Ovládací prvek přesnosti)

(Nepodporuje se na platformách ARM nebo x64.)
0x00030000 _PC_24 (24 bitů)

_PC_53 (53 bitů)

_PC_64 (64 bitů)
0x00020000

0x00010000

0x00000000

Požadavky

Rutina Požadovaný hlavičkový soubor
_controlfp_s <float.h>

Další informace o kompatibilitě najdete v tématu Kompatibilita.

Příklad

// crt_contrlfp_s.c
// processor: x86
// This program uses _controlfp_s to output the FP control
// word, set the precision to 24 bits, and reset the status to
// the default.

#include <stdio.h>
#include <float.h>
#pragma fenv_access (on)

int main( void )
{
    double a = 0.1;
    unsigned int control_word;
    int err;

    // Show original FP control word and do calculation.
    err = _controlfp_s(&control_word, 0, 0);
    if ( err ) /* handle error here */;

    printf( "Original: 0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Set precision to 24 bits and recalculate.
    err = _controlfp_s(&control_word, _PC_24, MCW_PC);
    if ( err ) /* handle error here */;

    printf( "24-bit:   0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Restore default precision-control bits and recalculate.
    err = _controlfp_s(&control_word, _CW_DEFAULT, MCW_PC);
    if ( err ) /* handle error here */;

    printf( "Default:  0x%.4x\n", control_word );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Original: 0x9001f
0.1 * 0.1 = 1.000000000000000e-002
24-bit:   0xa001f
0.1 * 0.1 = 9.999999776482582e-003
Default:  0x9001f
0.1 * 0.1 = 1.000000000000000e-002

Viz také

Podpora pro matematiku a plovoucí desetinou čárku
_clear87, _clearfp
_status87, _statusfp, _statusfp2
_control87, _controlfp, __control87_2