_controlfp_s

Mendapatkan dan mengatur kata kontrol floating-point. Versi _control87, _controlfp, __control87_2 ini memiliki peningkatan keamanan, seperti yang dijelaskan dalam Fitur keamanan di CRT.

Sintaks

errno_t _controlfp_s(
    unsigned int *currentControl,
    unsigned int newControl,
    unsigned int mask
);

Parameter

currentControl
Nilai bit kata kontrol saat ini.

newControl
Nilai bit kata kontrol baru.

mask
Masking untuk bit kata kontrol baru yang akan diatur.

Nilai hasil

Nol jika berhasil, atau errno kode kesalahan nilai.

Keterangan

Fungsi ini _controlfp_s adalah versi platform yang independen dan lebih aman dari _control87, yang mendapatkan kata kontrol floating-point ke dalam alamat yang disimpan currentControl dan mengaturnya dengan menggunakan newControl. Bit dalam nilai menunjukkan status kontrol floating-point. Status kontrol floating-point memungkinkan program untuk mengubah mode presisi, pembulatan, dan tak terbatas dalam paket matematika floating-point, tergantung pada platform. Anda juga dapat menggunakan _controlfp_s untuk menutupi atau membuka kemasan pengecualian floating-point.

Jika nilai untuk mask sama dengan 0, _controlfp_s mendapatkan kata kontrol floating-point dan menyimpan nilai yang diambil di currentControl.

Jika mask bukan nol, nilai baru untuk kata kontrol diatur: Untuk bit apa pun yang diatur (yaitu, sama dengan 1) di mask, bit yang sesuai di new digunakan untuk memperbarui kata kontrol. Dengan kata lain, fpcntrl = ((fpcntrl & ~mask) | (newControl & mask)) di mana fpcntrl adalah kata kontrol floating-point. Dalam skenario ini, currentControl diatur ke nilai setelah perubahan selesai; ini bukan nilai bit kata kontrol lama.

Catatan

Secara default, pustaka run-time menutupi semua pengecualian floating-point.

_controlfp_s hampir identik _control87 dengan fungsi pada platform Intel (x86), x64, dan ARM. Jika Anda menargetkan platform x86, x64, atau ARM, Anda dapat menggunakan _control87 atau _controlfp_s.

Perbedaan antara _control87 dan _controlfp_s adalah bagaimana mereka memperlakukan nilai denormal. Untuk platform Intel (x86), x64, dan ARM, _control87 dapat mengatur dan menghapus DENORMAL OPERAND masker pengecualian. _controlfp_s tidak mengubah DENORMAL OPERAND masker pengecualian. Contoh ini menunjukkan perbedaannya:

_control87( _EM_INVALID, _MCW_EM );
// DENORMAL is unmasked by this call.
unsigned int current_word = 0;
_controlfp_s( &current_word, _EM_INVALID, _MCW_EM );
// DENORMAL exception mask remains unchanged.

Nilai yang mungkin untuk konstanta masker (mask) dan nilai kontrol baru (newControl) diperlihatkan dalam tabel Nilai Heksadesimal berikut. Gunakan konstanta portabel yang tercantum di bawah ini (_MCW_EM, _EM_INVALID, dan sebagainya) sebagai argumen untuk fungsi-fungsi ini, daripada menyediakan nilai heksadesimal secara eksplisit.

Platform turunan Intel (x86) mendukung DENORMAL nilai input dan output dalam perangkat keras. Perilaku x86 adalah mempertahankan DENORMAL nilai. Platform ARM dan platform x64 yang memiliki dukungan SSE2 memungkinkan DENORMAL operand dan hasil untuk dibersihkan, atau dipaksa ke nol. Fungsi _controlfp_s, _controlfp, dan _control87 menyediakan masker untuk mengubah perilaku ini. Contoh berikut menunjukkan penggunaan masker ini:

unsigned int current_word = 0;
_controlfp_s(&current_word, _DN_SAVE, _MCW_DN);
// Denormal values preserved on ARM platforms and on x64 processors with
// SSE2 support. NOP on x86 platforms.
_controlfp_s(&current_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.

Pada platform ARM, _controlfp_s fungsi ini berlaku untuk register FPSCR. Pada arsitektur x64, hanya kata kontrol SSE2 yang disimpan di register MXCSR yang terpengaruh. Pada platform _controlfp_s Intel (x86), memengaruhi kata kontrol untuk x87 dan SSE2, jika ada. Dimungkinkan bagi dua kata kontrol agar tidak konsisten satu sama lain (karena panggilan sebelumnya ke __control87_2, misalnya); jika ada ketidakkonsistenan antara dua kata kontrol, _controlfp_s atur EM_AMBIGUOUS bendera di currentControl. Ini adalah peringatan bahwa kata kontrol yang dikembalikan mungkin tidak mewakili status kedua kata kontrol floating-point secara akurat.

Pada arsitektur ARM dan x64, mengubah mode tak terbatas atau presisi floating-point tidak didukung. Jika masker kontrol presisi digunakan pada platform x64, fungsi meningkatkan pernyataan dan handler parameter yang tidak valid dipanggil, seperti yang dijelaskan dalam Validasi parameter.

Jika masker tidak diatur dengan benar, fungsi ini menghasilkan pengecualian parameter yang tidak valid, seperti yang dijelaskan dalam Validasi parameter. Jika eksekusi diizinkan untuk melanjutkan, fungsi ini mengembalikan EINVAL dan mengatur errno ke EINVAL.

Fungsi ini diabaikan saat Anda menggunakan /clr (Common Language Runtime Compilation) untuk mengkompilasi karena runtime bahasa umum (CLR) hanya mendukung presisi floating-point default.

Secara default, status global fungsi ini dicakup ke aplikasi. Untuk mengubah perilaku ini, lihat Status global di CRT.

Menutupi konstanta dan nilai

_MCW_EM Untuk masker, menghapusnya menetapkan pengecualian, yang memungkinkan pengecualian perangkat keras; mengaturnya menyembunyikan pengecualian. Jika atau _EM_UNDERFLOW_EM_OVERFLOW terjadi, tidak ada pengecualian perangkat keras yang dilemparkan hingga instruksi floating-point berikutnya dijalankan. Untuk menghasilkan pengecualian perangkat keras segera setelah _EM_UNDERFLOW atau _EM_OVERFLOW, panggil FWAIT MASM instruksi.

Mask Nilai heks Terus-menerus Nilai heks
_MCW_DN (Denormal kontrol) 0x03000000 _DN_SAVE

_DN_FLUSH
0x00000000

0x01000000
_MCW_EM (Mengganggu masker pengecualian) 0x0008001F _EM_INVALID

_EM_DENORMAL

_EM_ZERODIVIDE

_EM_OVERFLOW

_EM_UNDERFLOW

_EM_INEXACT
0x00000010

0x00080000

0x00000008

0x00000004

0x00000002

0x00000001
_MCW_IC (Kontrol tak terbatas)

(Tidak didukung pada platform ARM atau x64.)
0x00040000 _IC_AFFINE

_IC_PROJECTIVE
0x00040000

0x00000000
_MCW_RC (Kontrol pembulatan) 0x00000300 _RC_CHOP

_RC_UP

_RC_DOWN

_RC_NEAR
0x00000300

0x00000200

0x00000100

0x00000000
_MCW_PC (Kontrol presisi)

(Tidak didukung pada platform ARM atau x64.)
0x00030000 _PC_24 (24 bit)

_PC_53 (53 bit)

_PC_64 (64 bit)
0x00020000

0x00010000

0x00000000

Persyaratan

Rutin Header yang diperlukan
_controlfp_s <float.h>

Untuk informasi kompatibilitas selengkapnya, lihat Kompatibilitas.

Contoh

// 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

Baca juga

Dukungan matematika dan titik mengambang
_clear87, _clearfp
_status87, _statusfp, _statusfp2
_control87, _controlfp, __control87_2