Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Возвращает и задает управляющее слово блока операций с плавающей запятой. Эта версия , _control87_controlfpимеет улучшения безопасности, как описано в функциях__control87_2безопасности в CRT.
Синтаксис
errno_t _controlfp_s(
unsigned int *currentControl,
unsigned int newControl,
unsigned int mask
);
Параметры
currentControl
Значения битов в текущем управляющем слове.
newControl
Значения битов в новом управляющем слове.
mask
Маска для установки битов нового управляющего слова.
Возвращаемое значение
Нуль в случае успешного выполнения или код ошибки errno.
Замечания
Функция _controlfp_s — это независимая от платформы и более безопасная версия функции _control87, которая получает управляющее слово с плавающей запятой в адрес, хранящийся в currentControl, и задает его с помощью newControl. Биты в значениях показывают состояние элемента управления блоком операций с плавающей запятой. Состояние элемента управления блока операций с плавающей запятой позволяет программе изменять режимы точности, округления и бесконечности в пакете математических операций с числами с плавающей запятой в зависимости от платформы. Можно также использовать функцию _controlfp_s для маскирования и демаскирования исключений, связанных с операциями с плавающей запятой.
Если значение для mask равно 0, функция _controlfp_s получает управляющее слово блока операций с плавающей запятой и сохраняет извлеченное значение в currentControl.
Если значение mask отлично от нуля, задается новое значение управляющего слова: для любого включенного бита (то есть равного 1) в параметре mask соответствующий бит в параметре new используется для обновления управляющего слова. Другими словами, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask)) где fpcntrl находится слово элемента управления с плавающей запятой. В этом сценарии currentControl задано значение после завершения изменения. Это не старое битовое значение элемента управления.
Примечание.
По умолчанию библиотеки времени выполнения маскируют все исключения для операций с плавающей запятой .
_controlfp_s почти идентичен _control87 функции на платформах Intel (x86), x64 и ARM. Если вы нацелены на платформы x86, x64 или ARM, можно использовать _control87 или _controlfp_s.
Разница между _control87 и _controlfp_s заключается в том, как они обрабатывают денормальные значения. Для платформ _control87 Intel (x86), x64 и ARM можно задать и очистить маску исключений DENORMAL OPERAND .
_controlfp_s не изменяет маску DENORMAL OPERAND исключения. В следующем примере показано это различие.
_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.
Возможные значения константы маски (mask) и новые управляющие значения (newControl) показаны в следующей таблице шестнадцатеричных значений. В аргументах этих функций вместо явных шестнадцатеричных значений следует использовать перечисленные ниже переносимые константы (_MCW_EM, _EM_INVALID и т. д.).
Платформы, производные от Intel (x86),поддерживают DENORMAL входные и выходные значения в оборудовании. Поведение x86 заключается в сохранении DENORMAL значений. Платформа ARM и платформы x64, поддерживающие SSE2, позволяют DENORMAL операндам и результатам удаляться или принудительно нулю. Функции _controlfp_s, _controlfp и _control87 предоставляют маску для изменения такого поведения. В следующем примере показано использование этой маски:
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.
Эта функция игнорируется при использовании /clr (компиляция среды CLR), так как среда CLR по умолчанию поддерживает только точность с плавающей запятой по умолчанию.
На x64 влияет только слово элемента управления SSE2, хранящееся в регистре MXCSR. Изменение режима бесконечности или точности с плавающей запятой не поддерживается. Если маска управления точностью используется на платформе x64, функция вызывает утверждение, а обработчик недопустимых параметров вызывается, как описано в разделе "Проверка параметров".
В x86 _controlfp_s влияет на слова элемента управления для x87 и SSE2, если они присутствуют. Два элемента управления могут быть несогласованы друг с другом (из-за предыдущего вызова__control87_2, например); если между двумя словами элемента управления возникает несоответствие, _controlfp_s задается EM_AMBIGUOUS флаг.currentControl Это предупреждение о том, что возвращаемое слово элемента управления может не представлять состояние обоих слов элемента управления с плавающей запятой точно.
Если маска не задана правильно, эта функция создает недопустимое исключение параметров, как описано в разделе проверки параметров. Если продолжение выполнения разрешено, эта функция возвращает EINVAL и задает для errno значение EINVAL.
По умолчанию глобальное состояние этой функции ограничивается приложением. Чтобы изменить это поведение, см. статью "Глобальное состояние" в CRT.
Платформы Arm
- Изменение режима бесконечности или точности с плавающей запятой не поддерживается. Если маска управления точностью используется на платформе x64, функция вызывает утверждение и вызывается обработчик недопустимых параметров, как описано в разделе "Проверка параметров".
- В ARM32 (прекращено), Windows не поддерживает исключения FP.
- В ARM64 отменяйте все
_MCW_EMили любые биты из него (_EM_INEXACT, ,_EM_UNDERFLOW_EM_OVERFLOW_EM_ZERODIVIDEи_EM_INVALID) правильно изменяйте регистр FPCR. Исключения с плавающей запятой, вызванные стандартными математическими функциями, такими как недопустимая операцияstd::acos, исключаются из этого поведения и могут быть проигнорированы или подняты должным образом в зависимости от регистра FPCR. Дополнительные сведения см. в разделе "Общие сведения о соглашениях ABI ARM32". - В ARM64EC Windows перехватывает исключения с плавающей запятой процессора и отключает их в регистре FPCR. Это обеспечивает согласованное поведение в разных вариантах процессора.
Маскирование констант и значений
При очистке маски _MCW_EM задается исключение, которое допускает аппаратное исключение; установка маски скрывает это исключение. Если возникает исключение _EM_UNDERFLOW или _EM_OVERFLOW, аппаратное исключение не создается, пока не будет выполняться следующая операция с плавающей запятой. Чтобы создать исключение оборудования сразу после _EM_UNDERFLOW или _EM_OVERFLOWвызовите инструкцию FWAIT MASM .
| Маска | Шестнадцатеричное значение | Константа | Шестнадцатеричное значение |
|---|---|---|---|
_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 |
Требования
| Маршрут | Обязательный заголовок |
|---|---|
_controlfp_s |
<float.h> |
Дополнительные сведения о совместимости см. в разделе "Совместимость".
Пример
// 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
См. также
Поддержка математических и плавающих точек
_clear87, _clearfp
_status87, , _statusfp_statusfp2
_control87, , _controlfp__control87_2