Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Hämtar och anger flyttalskontrollens ord. Den här versionen av _control87, _controlfphar __control87_2 säkerhetsförbättringar enligt beskrivningen i Säkerhetsfunktioner i CRT.
Syntax
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Parameterar
currentControl
Det aktuella bitvärdet control-word.
newControl
Nya bitvärden för kontroll-ord.
mask
Maskera för nya control-word-bitar som ska anges.
Returvärde
Noll om det lyckas eller en errno värdefelkod.
Anmärkningar
Funktionen _controlfp_s är en plattformsoberoende och säkrare version av _control87, som hämtar flyttalskontrollens ord till den adress som lagras i currentControl och anger den med hjälp newControlav . Bitarna i värdena anger flyttalskontrollens tillstånd. Med kontrolltillståndet för flyttal kan programmet ändra precisions-, avrundnings- och oändlighetslägena i det flyttalsbaserade matematikpaketet, beroende på plattformen. Du kan också använda _controlfp_s för att maskera eller avmaskera undantag från flyttalser.
Om värdet för mask är lika med 0 _controlfp_s hämtar du flyttalskontrollens ord och lagrar det hämtade värdet i currentControl.
Om mask är nonzero anges ett nytt värde för kontrollordet: För varje bit som har angetts (dvs. lika med 1) i maskanvänds motsvarande bit i new för att uppdatera kontrollordet. Med andra ord, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask)) var fpcntrl är flyttalskontrollens ord. I det här scenariot currentControl anges värdet efter att ändringen har slutförts. Det är inte det gamla bitvärdet för kontroll-ord.
Anmärkning
Som standard maskerar körningsbiblioteken alla undantag från flyttal.
_controlfp_s är nästan identisk med _control87 funktionen på Intel-plattformarna (x86), x64 och ARM. Om du riktar in dig på x86-, x64- eller ARM-plattformar kan du använda _control87 eller _controlfp_s.
Skillnaden mellan _control87 och _controlfp_s är i hur de behandlar denormala värden. För Intel-plattformar _control87 (x86), x64 och ARM kan du ange och rensa undantagsmasken DENORMAL OPERAND .
_controlfp_s ändrar inte undantagsmasken DENORMAL OPERAND . Det här exemplet visar skillnaden:
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call.
unsigned int current_word = 0;
_controlfp_s( ¤t_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.
Möjliga värden för maskkonstanten (mask) och nya kontrollvärden (newControl) visas i följande hexadecimala värden. Använd de portabla konstanterna som anges nedan (_MCW_EM, _EM_INVALIDoch så vidare) som argument för dessa funktioner i stället för att uttryckligen ange hexadecimala värden.
Intel-härledda plattformar (x86) stöder DENORMAL indata- och utdatavärdena i maskinvaran. X86-beteendet är att bevara DENORMAL värden. ARM-plattformen och de x64-plattformar som har stöd för SSE2 gör att DENORMAL operander och resultat kan tömmas eller tvingas till noll. Funktionerna _controlfp_s, _controlfpoch _control87 ger en mask för att ändra det här beteendet. I följande exempel visas hur masken används:
unsigned int current_word = 0;
_controlfp_s(¤t_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(¤t_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.
Den här funktionen ignoreras när du använder /clr (Common Language Runtime Compil) för att kompilera eftersom CLR (Common Language Runtime) endast stöder standardprecision för flyttals.
På x64 påverkas endast SSE2-kontrollordet som lagras i MXCSR-registret. Det går inte att ändra oändlighetsläget eller flyttalsprecisionen. Om precisionskontrollmasken används på x64-plattformen genererar funktionen ett påstående och den ogiltiga parameterhanteraren anropas enligt beskrivningen i Parameterverifiering.
På x86 _controlfp_s påverkar kontrollorden för både x87 och SSE2, om det finns. Det är möjligt att de två kontrollorden är inkonsekventa med varandra (på grund av ett tidigare anrop till , till __control87_2exempel); om det finns en inkonsekvens mellan de två kontrollorden _controlfp_sEM_AMBIGUOUS anger du flaggan i currentControl. Det är en varning om att det returnerade kontrollordet kanske inte representerar tillståndet för båda flyttalskontrollorden korrekt.
Om masken inte är korrekt inställd genererar den här funktionen ett ogiltigt parameterfel, enligt beskrivningen i Parameterverifiering. Om körningen tillåts fortsätta returneras EINVAL och anges errno den här funktionen till EINVAL.
Som standard är den här funktionens globala tillstånd begränsat till programmet. Information om hur du ändrar det här beteendet finns i Globalt tillstånd i CRT.
Armplattformar
- Det går inte att ändra oändlighetsläget eller flyttalsprecisionen. Om precisionskontrollmasken används på x64-plattformen genererar funktionen ett påstående och den ogiltiga parameterhanteraren anropas enligt beskrivningen i Parameterverifiering.
- På ARM32 (upphört) stöder Windows inte FP-undantag.
- På ARM64 ändrar du FPCR-registret korrekt genom att avmaskera hela
_MCW_EMeller några bitar från det (_EM_INEXACT, ,_EM_UNDERFLOW_EM_OVERFLOW_EM_ZERODIVIDE, och )._EM_INVALIDUndantag från flyttal som genereras av standardmatematikfunktioner, till exempel Ogiltig åtgärd frånstd::acos, är undantagna från det här beteendet och kan ignoreras eller höjas korrekt beroende på FPCR-registret. Mer information finns i Översikt över ARM32 ABI-konventioner. - På ARM64EC fångar Windows undantag från processorns flyttal och inaktiverar dem i FPCR-registret. Detta säkerställer konsekvent beteende för olika processorvarianter.
Maskera konstanter och värden
För masken _MCW_EM anger rensningen undantaget, vilket tillåter maskinvarufelet. Om du anger det döljs undantaget. Om en _EM_UNDERFLOW eller _EM_OVERFLOW inträffar utlöses inget maskinvaruundantag förrän nästa flyttalsinstruktion körs. Om du vill generera ett maskinvarufel direkt efter _EM_UNDERFLOW eller _EM_OVERFLOWanropar du instruktionen FWAIT MASM .
| Ansiktsmask | Hexvärde | Konstant | Hexvärde |
|---|---|---|---|
_MCW_DN (Denormal kontroll) |
0x03000000 | _DN_SAVE_DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (Avbryt undantagsmask) |
0x0008001F | _EM_INVALID_EM_DENORMAL_EM_ZERODIVIDE_EM_OVERFLOW_EM_UNDERFLOW_EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Oändlig kontroll)(Stöds inte på ARM- eller x64-plattformar.) |
0x00040000 | _IC_AFFINE_IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Avrundningskontroll) |
0x00000300 | _RC_CHOP_RC_UP_RC_DOWN_RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Precisionskontroll)(Stöds inte på ARM- eller x64-plattformar.) |
0x00030000 |
_PC_24 (24 bitar)_PC_53 (53 bitar)_PC_64 (64 bitar) |
0x00020000 0x00010000 0x00000000 |
Kravspecifikation
| Rutin | Obligatoriskt huvud |
|---|---|
_controlfp_s |
<float.h> |
Mer kompatibilitetsinformation finns i Kompatibilitet.
Exempel
// 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
Se även
Stöd för matematik och flyttals
_clear87, _clearfp
_status87, , _statusfp_statusfp2
_control87, , _controlfp__control87_2