Поделиться через


_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 на Intel (x86), x64 и ARM платформах. Если приложение предназначено для x86, x64 или ARM платформ, используйте _control87 или _controlfp.

Разница между _control87 и _controlfp состоит в том, как они обрабатывают значения DENORMAL. Для Intel (x86), x64 и ARM платформ _control87 может устанавливать и убирать маску исключения 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 и платформы 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.

На платформах ARM функции _control87 и _controlfp применяются к регистру FPSCR. В архитектурах x64 затрагивается только управляющее слово SSE2, хранящееся в регистре MXCSR. На платформах Intel (x86) _control87 и _controlfp влияют на управляющие слова как для x87, так и для SSE2, если они есть. Функция __control87_2 включает блок выполнения операций с плавающей точкой и для x87, и для SSE2, чтобы контролировать из совместно или по отдельности. Если требуется повлиять на оба блока, следует передать адреса двух целых чисел в x86_cw и sse2_cw. Если требуется повлиять только на один блок, следует передать адрес для этого параметра, но передать 0 (NULL) для другого. Если передается 0 для одного из этих параметров, то функция не влияет на этот блок выполнения операций с плавающей точкой. Эта функция может быть полезна в ситуациях, когда часть кода использует x87 блок выполнения операций с плавающей точкой, и другая часть кода использует SSE2 блок выполнения операций с плавающей точкой. В случае использования __control87_2 в одной части программы и установки различных значений для управляющих слов с плавающей точкой, а затем указания _control87 или _controlfp для дальнейших операций над управляющим словом, _control87 и _controlfp могут быть не способны возвращать одно управляющее слово для представления состояние обеих блоков выполнения операций с плавающей точкой. В таком случае эти функции установят флажок EM_AMBIGUOUS в возвращенном целочисленном значении, чтобы указать, что есть несоответствия между двумя управляющими словами. Это предупреждение о том, что возвращенное управляющее слово не может точно представлять состояние обоих управляющих слов с плавающей точкой.

В архитектурах ARM и x64 не поддерживается изменение режима бесконечности или точности чисел с плавающей точкой. Если маска управления точностью используется на платформе x64, то функция создает утверждение и вызывается обработчик недопустимого параметра, как описано в разделе Проверка параметров.

Примечание

__control87_2 не поддерживается в архитектурах ARM или x64.Если используется __control87_2, и программа компилируется для архитектур ARM или x64, то компилятор выдает ошибку.

Эти функции игнорируются в случае использования /clr (компиляция CLR) или /clr:pure для компилирования, поскольку среда CLR поддерживает только точность чисел с плавающей точкой по умолчанию.

Шестнадцатеричные значения

Для маски _MCW_EM, очистка маски задает исключение, которое допускает аппаратное исключение; установка маски скрывает исключение. Если возникает _EM_UNDERFLOW или _EM_OVERFLOW, не аппаратное исключение не создается до тех пор, пока не выполнится следующая инструкций с плавающей точкой. Для создания аппаратного исключения сразу после _EM_UNDERFLOW или _EM_OVERFLOW, следует вызвать инструкцию MASM FWAIT.

Маска

Шестнадцатеричное значение

Константа

Шестнадцатеричное значение

_MCW_DN (управление Denormal)

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 (управление бесконечностью)

(Не поддерживается на платформах x64 или ARM).

0x00040000

_IC_AFFINE

_IC_PROJECTIVE

0x00040000

0x00000000

_MCW_RC (управление округлением)

0x00000300

_RC_CHOP

_RC_UP

_RC_DOWN

_RC_NEAR

0x00000300

0x00000200

0x00000100

0x00000000

_MCW_PC (управление точностью)

(Не поддерживается на платформах x64 или ARM).

0x00030000

_PC_24 (24 бита)

_PC_53 (53 бита)

_PC_64 (64 бита)

0x00020000

0x00010000

0x00000000

Требования

Подпрограмма

Обязательный заголовок

_control87, _controlfp, _control87_2

<float.h>

Дополнительные сведения о совместимости см. в разделе Совместимость.

Пример

// crt_cntrl87.c
// processor: x86
// 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;

    // Show original x87 control word and do calculation.
    control_word_x87 = __control87_2(0, 0,
                                     &control_word_x87, 0);
    printf( "Original: 0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Set precision to 24 bits and recalculate.
    control_word_x87 = __control87_2(_PC_24, MCW_PC,
                                     &control_word_x87, 0);
    printf( "24-bit:   0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );

    // Restore default precision-control bits and recalculate.
    control_word_x87 = __control87_2( _CW_DEFAULT, MCW_PC, 
                                     &control_word_x87, 0 );
    printf( "Default:  0x%.4x\n", control_word_x87 );
    printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
}

Output

Original: 0x0001
0.1 * 0.1 = 1.000000000000000e-002
24-bit:   0x0001
0.1 * 0.1 = 9.999999776482582e-003
Default:  0x0001
0.1 * 0.1 = 1.000000000000000e-002

Эквивалент в .NET Framework

Неприменимо. Для вызова стандартной функции C используйте PInvoke. Для получения дополнительной информации см. Примеры вызовов неуправляемого кода.

См. также

Ссылки

Поддержка чисел с плавающей запятой

_clear87, _clearfp

_status87, _statusfp, _statusfp2

_controlfp_s