_control87
, , _controlfp
__control87_2
Возвращает и задает управляющее слово блока операций с плавающей запятой. Более безопасная версия _controlfp
доступна; см. раздел _controlfp_s
.
Синтаксис
unsigned int _control87(
unsigned int new,
unsigned int mask
);
unsigned int _controlfp(
unsigned int new,
unsigned int mask
);
int __control87_2(
unsigned int new,
unsigned int mask,
unsigned int* x86_cw,
unsigned int* sse2_cw
);
Параметры
new
Значения битов в новом управляющем слове.
mask
Маска для установки битов нового управляющего слова.
x86_cw
Заполняется управляющим словом для блока операций с плавающей запятой x87. Передайте 0 (NULL
), чтобы задать только управляющее слово SSE2.
sse2_cw
Управляющее слово для блока операций с плавающей запятой SSE. Передайте 0 (NULL
), чтобы задать только управляющее слово x87.
Возвращаемое значение
Для _control87
и _controlfp
биты возвращаемого значения показывают состояние управления блоком операций с плавающей запятой. Полное определение битов, возвращаемых _control87
, см. в разделе FLOAT.H
.
Для __control87_2
возвращаемое значение равно 1, что означает успешное завершение.
Замечания
Функция _control87
получает и задает управляющее слово блока операций с плавающей запятой. Слово управления с плавающей запятой позволяет программе изменять режимы точности, округления и бесконечности в зависимости от платформы. Можно также использовать функцию _control87
для маскирования и демаскирования исключений, связанных с операциями с плавающей запятой. Если значение для mask
равно 0, функция _control87
получает управляющее слово блока операций с плавающей запятой. Если значение mask
отлично от нуля, задается новое значение управляющего слова: для любого включенного бита (то есть, равного 1) в параметре mask
соответствующий бит в параметре new
используется для обновления управляющего слова. Другими словами, fpcntrl = ((fpcntrl & ~mask) | (new & mask))
где fpcntrl
находится слово элемента управления с плавающей запятой.
Примечание.
По умолчанию библиотеки времени выполнения маскируют все исключения для операций с плавающей запятой .
_controlfp
— это независимая от платформы переносимая версия _control87
, которая почти идентична _control87
функции. Если код предназначен для нескольких платформ, используйте _controlfp
или _controlfp_s
. Разница между функциями _control87
и _controlfp
состоит в способе обработки значения DENORMAL
. Для платформ _control87
x86, x64, ARM и ARM64 можно задать и очистить маску исключений DENORMAL OPERAND
. _controlfp
не изменяет маску DENORMAL OPERAND
исключения. В следующем примере показано это различие.
_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call
_controlfp( _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged
Возможные значения для константы маски (mask
) и новых значений элемента управления (new
) отображаются в таблице "Маски и значения элемента управления". В аргументах этих функций вместо явных шестнадцатеричных значений следует использовать перечисленные ниже переносимые константы (_MCW_EM
, _EM_INVALID
и т. д.).
Платформы, производные от Intel x86, поддерживают DENORMAL
входные и выходные значения в оборудовании. Поведение x86 заключается в сохранении DENORMAL
значений. Платформы ARM и ARM64 и платформы x64 с поддержкой SSE2 позволяют DENORMAL
выполнять очистку операндов и результатов или принудительно нулю. Функции _controlfp
и _control87
предоставляют маску для изменения такого поведения. В следующем примере показано использование этой маски.
_controlfp(_DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp(_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.
На платформах _control87
_controlfp
ARM и ARM64 функции применяются к регистру FPSCR. На платформах x64 влияет только слово управления SSE2, хранящееся в регистре MXCSR. На платформах _control87
x86 и _controlfp
повлиять на слова элемента управления для x87 и SSE2, если они присутствуют.
Функция __control87_2
позволяет управлять блоками операций с плавающей запятой x87 и SSE2 как совместно, так и раздельно. Чтобы повлиять на оба блока, передайте адреса двух целых x86_cw
чисел и sse2_cw
. Если вы хотите повлиять только на одну единицу, передайте адрес для этого параметра, но передайте 0 (NULL
) для другого. Если для одного из этих параметров передано значение 0, данная функция не влияет на этот блок операций с плавающей запятой. Полезно, если часть кода использует единицу с плавающей запятой x87, а другая часть использует единицу с плавающей запятой SSE2.
Если вы используете __control87_2
для задания разных значений слов элемента управления с плавающей запятой, то _control87
или _controlfp
не удается вернуть одно контрольное слово для представления состояния обоих единиц с плавающей запятой. В таком случае эти функции задают EM_AMBIGUOUS
флаг в возвращаемом целочисленном значении, чтобы указать несоответствие между двумя словами элемента управления. Флаг EM_AMBIGUOUS
является предупреждением о том, что возвращаемое слово элемента управления может не представлять состояние обоих слов элемента управления с плавающей запятой точно.
На платформах ARM, ARM64 и x64 изменение режима бесконечности или точность с плавающей запятой не поддерживается. Если маска управления точностью используется на платформе x64, функция вызывает утверждение, а обработчик недопустимых параметров вызывается, как описано в разделе проверки параметров.
Примечание.
__control87_2
не поддерживается на платформах ARM, ARM64 или x64. Если вы используете __control87_2
и компилируете программу для платформ ARM, ARM64 или x64, компилятор создает ошибку.
Эти функции игнорируются при использовании /clr
(компиляция среды CLR) для компиляции. Среда CLR поддерживает только точность с плавающей запятой по умолчанию.
Управление масками слов и значениями
В случае маски _MCW_EM
очистка маски задает исключение, которое допускает аппаратное исключение; установка маски скрывает исключение. Если возникает исключение _EM_UNDERFLOW
или _EM_OVERFLOW
, аппаратное исключение не создается, пока не будет выполняться следующая операция с плавающей запятой. Чтобы аппаратное исключение возникало сразу после _EM_UNDERFLOW
или _EM_OVERFLOW
, следует вызвать инструкцию MASM FWAIT
.
Маска | Шестнадцатеричное значение | Константа | Шестнадцатеричное значение |
---|---|---|---|
_MCW_DN (управление денормализацией) |
0x03000000 | _DN_SAVE _DN_FLUSH |
0x00000000 0x01000000 |
_MCW_EM (маска исключения прерывания) |
0x0008001F | _EM_INVALID _EM_DENORMAL _EM_ZERODIVIDE _EM_OVERFLOW _EM_UNDERFLOW _EM_INEXACT |
0x00000010 0x00080000 0x00000008 0x00000004 0x00000002 0x00000001 |
_MCW_IC (управление бесконечностью)(Не поддерживается на платформах ARM или x64.) |
0x00040000 | _IC_AFFINE _IC_PROJECTIVE |
0x00040000 0x00000000 |
_MCW_RC (управление округлением) |
0x00000300 | _RC_CHOP _RC_UP _RC_DOWN _RC_NEAR |
0x00000300 0x00000200 0x00000100 0x00000000 |
_MCW_PC (управление точностью)(Не поддерживается на платформах ARM или x64.) |
0x00030000 | _PC_24 (24 бита)_PC_53 (53 бита)_PC_64 (64 бита) |
0x00020000 0x00010000 0x00000000 |
Требования
Маршрут | Обязательный заголовок |
---|---|
_control87 , , _controlfp _control87_2 |
<float.h> |
Дополнительные сведения о совместимости см. в разделе Совместимость.
Пример
// crt_cntrl87.c
// processor: x86
// compile by using: cl /W4 /arch:IA32 crt_cntrl87.c
// This program uses __control87_2 to output the x87 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_x87 = 0;
int result;
// Show original x87 control word and do calculation.
result = __control87_2(0, 0, &control_word_x87, 0 );
printf( "Original: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Set precision to 24 bits and recalculate.
result = __control87_2(_PC_24, MCW_PC, &control_word_x87, 0 );
printf( "24-bit: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
// Restore default precision-control bits and recalculate.
result = __control87_2( _CW_DEFAULT, MCW_PC, &control_word_x87, 0 );
printf( "Default: 0x%.8x\n", control_word_x87 );
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}
Original: 0x0009001f
0.1 * 0.1 = 1.000000000000000e-02
24-bit: 0x000a001f
0.1 * 0.1 = 9.999999776482582e-03
Default: 0x0009001f
0.1 * 0.1 = 1.000000000000000e-02
См. также
Поддержка математических и плавающих точек
_clear87
, _clearfp
_status87
, , _statusfp
_statusfp2
_controlfp_s