_controlfp_s
Ruft das Gleitkommasteuerwort ab und legt es fest. Diese Version von _control87
, _controlfp
__control87_2
hat Sicherheitsverbesserungen, wie in sicherheitsfeatures in der CRT beschrieben.
Syntax
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Parameter
currentControl
Der aktuelle Bitwert des Steuerworts.
newControl
Neue Bitwerte des Steuerworts.
mask
Maske für festzulegende neue Steuerwortbits.
Rückgabewert
Null, wenn erfolgreich, oder ein Fehlercode des Wertes errno
.
Hinweise
Die _controlfp_s
-Funktion ist eine plattformunabhängige und sicherere Version von _control87
, die das Gleitkommasteuerwort in die in currentControl
gespeicherte Adresse einsetzt und mithilfe von newControl
festlegt. Die Bits in den Werten geben den Zustand des Gleitkommasteuerelements an. Mit dem Zustand des Gleitkommasteuerelements kann das Programm die Genauigkeits-, Rundungs- und Unendlichkeitsmodi im mathematischen Gleitkommapaket je nach Plattform ändern. Sie können auch _controlfp_s
verwenden, um Gleitkommaausnahmen zu maskieren bzw. die Maskierung aufzuheben.
Wenn der Wert für mask
gleich 0 ist, ruft _controlfp_s
das Gleitkommasteuerwort ab und speichert den abgerufenen Wert in currentControl
.
Wenn mask
ungleich 0 ist, wird ein neuer Wert für das Steuerwort festgelegt: Für jedes festgelegte Bit (d. h. gleich 1) in mask
wird das entsprechende Bit in new
verwendet, um das Steuerwort zu aktualisieren. Mit anderen Worten: fpcntrl = ((fpcntrl & ~mask) | (newControl & mask))
Wo fpcntrl
befindet sich das Gleitkomma-Steuerelementwort. In diesem Szenario currentControl
wird der Wert nach Abschluss der Änderung auf den Wert festgelegt. Es handelt sich nicht um den alten Bitwert des Steuerelements.
Hinweis
Standardmäßig maskieren die Laufzeitbibliotheken alle Gleitkommaausnahmen.
_controlfp_s
ist nahezu identisch mit der _control87
Funktion auf Intel -Plattformen (x86), x64 und ARM. Wenn Sie auf x86-, x64- oder ARM-Plattformen abzielen, können Sie diese verwenden _control87
oder _controlfp_s
.
Der Unterschied zwischen _control87
und _controlfp_s
ist in der Behandlung von Denormalwerten. Für Intel -Plattformen _control87
(x86), x64 und ARM kann die DENORMAL OPERAND
Ausnahmemaske festgelegt und gelöscht werden. _controlfp_s
ändert das DENORMAL OPERAND
Ausnahmeformat nicht. Dieses Beispiel veranschaulicht den Unterschied:
_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.
Die möglichen Werte für die Maskenkonstante (mask
) und die neuen Steuerelementwerte (newControl
) sind in der folgenden Hexadezimalwerttabelle aufgeführt. Verwenden die unten aufgeführten portablen Konstanten (_MCW_EM
, _EM_INVALID
usw.) als Argumente für diese Funktionen, anstatt den Hexadezimalwerten explizit anzugeben.
Intel (x86)-abgeleitete Plattformen unterstützen die Eingabe- und Ausgabewerte in der DENORMAL
Hardware. Das x86-Verhalten besteht darin, Werte beizubehalten DENORMAL
. Die ARM-Plattform und die x64-Plattformen mit SSE2-Unterstützung ermöglichen DENORMAL
es Operanden und Ergebnissen zu leeren oder auf Null zu zwingen. Die Funktionen _controlfp_s
, _controlfp
und _control87
stellen eine Maske zum Ändern dieses Verhaltens bereit. Das folgende Beispiel veranschaulicht die Verwendung dieser Maske:
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.
Auf ARM-Plattformen gilt die _controlfp_s
-Funktion für das FPSCR-Register. Bei x64-Architekturen ist nur das im MXCSR-Register gespeicherte SSE2-Steuerelementwort betroffen. Auf Intel (x86)-Plattformen wirkt sich _controlfp_s
sowohl bei x87 als auch bei SSE2 (sofern vorhanden) auf die Steuerworte aus. Es ist möglich, dass die beiden Steuerelementwörter miteinander inkonsistent sind (z. B. aufgrund eines vorherigen Aufrufs __control87_2
von , z. B.), wenn es eine Inkonsistenz zwischen den beiden Steuerelementwörtern gibt, _controlfp_s
legt die EM_AMBIGUOUS
Kennzeichnung in currentControl
fest. Es ist eine Warnung, dass das zurückgegebene Steuerelementwort möglicherweise nicht den Zustand beider Gleitkomma-Steuerwörter genau darstellt.
Bei den ARM- und x64-Architekturen wird das Ändern des Unendlichkeitsmodus oder der Gleitkommagenauigkeit nicht unterstützt. Wenn die Genauigkeitssteuerungsmaske auf der x64-Plattform verwendet wird, löst die Funktion eine Assertion aus, und der ungültige Parameterhandler wird aufgerufen, wie in der Parameterüberprüfung beschrieben.
Wenn die Maske nicht ordnungsgemäß festgelegt ist, generiert diese Funktion eine ungültige Parameter-Ausnahme, wie in der Parameterüberprüfung beschrieben. Wenn die weitere Ausführung zugelassen wird, gibt diese Funktion EINVAL
zurück und stellt errno
auf EINVAL
ein.
Diese Funktion wird ignoriert, wenn Sie die Kompilierung (Common Language Runtime Compilation) verwenden /clr
, da die Common Language Runtime (CLR) nur die Standard-Gleitkommagenauigkeit unterstützt.
Standardmäßig gilt der globale Zustand dieser Funktion für die Anwendung. Wie Sie dieses Verhalten ändern, erfahren Sie unter Globaler Status in der CRT.
Maskenkonstanten und -werte
Durch das Aufheben der _MCW_EM
-Maske wird die Ausnahme festgelegt, was die Hardwareausnahme ermöglicht. Das Festlegen der Maske blendet die Ausnahme aus. Wenn _EM_UNDERFLOW
oder _EM_OVERFLOW
auftritt, wird keine Hardwareausnahme ausgelöst, bis die nächste Gleitkommaanweisung ausgeführt wird. Rufen Sie die FWAIT MASM
Anweisung auf, um unmittelbar nach _EM_UNDERFLOW
oder _EM_OVERFLOW
nach eine Hardware-Ausnahme zu generieren.
Maske | Farbtonwert | Konstante | Farbtonwert |
---|---|---|---|
_MCW_DN (Nicht normale Steuerung) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (Unterbrechungsausnahmemaske) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (Unendlichkeitssteuerung)(Nicht unterstützt auf ARM- oder x64-Plattformen.) |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (Rundungssteuerung) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (Genauigkeitssteuerung)(Nicht unterstützt auf ARM- oder x64-Plattformen.) |
0x00030000 | _PC_24 (24 Bits)_PC_53 (53 Bits)_PC_64 (64 Bits) |
0x00020000 0x00010000 0x00000000 |
Anforderungen
Routine | Erforderlicher Header |
---|---|
_controlfp_s |
<float.h> |
Weitere Informationen zur Kompatibilität finden Sie unter Kompatibilität.
Beispiel
// 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
Siehe auch
Mathematische Unterstützung und Gleitkommaunterstützung
_clear87
, _clearfp
_status87
, _statusfp
_statusfp2
_control87
, _controlfp
__control87_2