Skip to content

Commit b84fad6

Browse files
Merge pull request MicrosoftDocs#2277 from corob-msft/cr-1532
Fix code for issue 1532
2 parents 31fd80a + 712bf5d commit b84fad6

File tree

1 file changed

+39
-38
lines changed

1 file changed

+39
-38
lines changed

docs/c-runtime-library/reference/control87-controlfp-control87-2.md

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "_control87, _controlfp, __control87_2"
3-
ms.date: "04/05/2018"
3+
ms.date: "08/29/2019"
44
apiname: ["_control87", "_controlfp", "__control87_2"]
55
apilocation: ["msvcrt.dll", "msvcr80.dll", "msvcr90.dll", "msvcr100.dll", "msvcr100_clr0400.dll", "msvcr110.dll", "msvcr110_clr0400.dll", "msvcr120.dll", "msvcr120_clr0400.dll", "ucrtbase.dll", "api-ms-win-crt-runtime-l1-1-0.dll"]
66
apitype: "DLLExport"
@@ -33,34 +33,32 @@ int __control87_2(
3333

3434
### Parameters
3535

36-
*new*<br/>
36+
*new*\
3737
New control-word bit values.
3838

39-
*mask*<br/>
39+
*mask*\
4040
Mask for new control-word bits to set.
4141

42-
*x86_cw*<br/>
42+
*x86_cw*\
4343
Filled in with the control word for the x87 floating-point unit. Pass in 0 (**NULL**) to set only the SSE2 control word.
4444

45-
*sse2_cw*<br/>
45+
*sse2_cw*\
4646
Control word for the SSE floating-point unit. Pass in 0 (**NULL**) to set only the x87 control word.
4747

48-
## Return Value
48+
## Return value
4949

5050
For **_control87** and **_controlfp**, the bits in the value returned indicate the floating-point control state. For a complete definition of the bits that are returned by **_control87**, see FLOAT.H.
5151

5252
For **__control87_2**, the return value is 1, which indicates success.
5353

5454
## Remarks
5555

56-
The **_control87** function gets and sets the floating-point control word. The floating-point control word enables the program to change the precision, rounding, and infinity modes in the floating-point math package, depending on the platform. You can also use **_control87** to mask or unmask floating-point exceptions. If the value for *mask* is equal to 0, **_control87** gets the floating-point control word. If *mask* is nonzero, a new value for the control word is set: For any bit that is on (that is, equal to 1) in *mask*, the corresponding bit in *new* is used to update the control word. In other words, **fpcntrl** = ((**fpcntrl** & ~*mask*) &#124; (*new* & *mask*)) where **fpcntrl** is the floating-point control word.
56+
The **_control87** function gets and sets the floating-point control word. The floating-point control word enables the program to change the precision, rounding, and infinity modes, depending on the platform. You can also use **_control87** to mask or unmask floating-point exceptions. If the value for *mask* is equal to 0, **_control87** gets the floating-point control word. If *mask* is nonzero, a new value for the control word is set: For any bit that is on (that is, equal to 1) in *mask*, the corresponding bit in *new* is used to update the control word. In other words, **fpcntrl** = ((**fpcntrl** & ~*mask*) &#124; (*new* & *mask*)) where **fpcntrl** is the floating-point control word.
5757

5858
> [!NOTE]
5959
> By default, the run-time libraries mask all floating-point exceptions.
6060
61-
**_controlfp** is a platform-independent, portable version of **_control87**. It is nearly identical to the **_control87** function on x86, x64, and ARM platforms. If you are targeting x86, x64, or ARM platforms, use **_control87** or **_controlfp**.
62-
63-
The difference between **_control87** and **_controlfp** is in how they treat DENORMAL values. For x86, x64, and ARM platforms, **_control87** can set and clear the DENORMAL OPERAND exception mask. **_controlfp** does not modify the DENORMAL OPERAND exception mask. This example demonstrates the difference:
61+
**_controlfp** is a platform-independent, portable version of **_control87** that's nearly identical to the **_control87** function. If your code targets more than one platform, use **_controlfp** or **_controlfp_s**. The difference between **_control87** and **_controlfp** is in how they treat DENORMAL values. For x86, x64, ARM, and ARM64 platforms, **_control87** can set and clear the DENORMAL OPERAND exception mask. **_controlfp** doesn't modify the DENORMAL OPERAND exception mask. This example demonstrates the difference:
6462

6563
```C
6664
_control87( _EM_INVALID, _MCW_EM );
@@ -69,9 +67,9 @@ _controlfp( _EM_INVALID, _MCW_EM );
6967
// DENORMAL exception mask remains unchanged
7068
```
7169
72-
The possible values for the mask constant (*mask*) and new control values (*new*) are shown in the following Hexadecimal Values table. Use the portable constants listed below (**_MCW_EM**, **_EM_INVALID**, and so forth) as arguments to these functions, rather than supplying the hexadecimal values explicitly.
70+
The possible values for the mask constant (*mask*) and new control values (*new*) are shown in the Control word masks and values table. Use the portable constants listed below (**_MCW_EM**, **_EM_INVALID**, and so forth) as arguments to these functions, rather than supplying the hexadecimal values explicitly.
7371
74-
Intel x86-derived platforms support the DENORMAL input and output values in hardware. The x86 behavior is to preserve DENORMAL values. The ARM platform and the x64 platforms that have SSE2 support enable DENORMAL operands and results to be flushed, or forced to zero. The **_controlfp** and **_control87** functions provide a mask to change this behavior. The following example demonstrates the use of this mask.
72+
Intel x86-derived platforms support the DENORMAL input and output values in hardware. The x86 behavior is to preserve DENORMAL values. The ARM and ARM64 platforms and the x64 platforms that have SSE2 support enable DENORMAL operands and results to be flushed, or forced to zero. The **_controlfp** and **_control87** functions provide a mask to change this behavior. The following example demonstrates the use of this mask.
7573
7674
```C
7775
_controlfp(_DN_SAVE, _MCW_DN);
@@ -82,24 +80,28 @@ _controlfp(_DN_FLUSH, _MCW_DN);
8280
// and x64 processors with SSE2 support. Ignored on other x86 platforms.
8381
```
8482

85-
On ARM platforms, the **_control87** and **_controlfp** functions apply to the FPSCR register. On x64 architectures, only the SSE2 control word that's stored in the MXCSR register is affected. On x86 platforms, **_control87** and **_controlfp** affect the control words for both the x87 and the SSE2, if present. The function **__control87_2** enables both the x87 and SSE2 floating-point units to be controlled together or separately. If you want to affect both units, pass in the addresses of two integers to **x86_cw** and **sse2_cw**. If you only want to affect one unit, pass in an address for that parameter but pass in 0 (**NULL**) for the other. If 0 is passed for one of these parameters, the function has no effect on that floating-point unit. This functionality could be useful in situations where part of the code uses the x87 floating-point unit and another part of the code uses the SSE2 floating-point unit. If you use **__control87_2** in one part of a program and set different values for the floating-point control words, and then use **_control87** or **_controlfp** to further manipulate the control word, then **_control87** and **_controlfp** might be unable to return a single control word to represent the state of both floating-point units. In such a case, these functions set the **EM_AMBIGUOUS** flag in the returned integer value to indicate that there is an inconsistency between the two control words. This is a warning that the returned control word might not represent the state of both floating-point control words accurately.
83+
On ARM and ARM64 platforms, the **_control87** and **_controlfp** functions apply to the FPSCR register. Only the SSE2 control word that's stored in the MXCSR register is affected on x64 platforms. On x86 platforms, **_control87** and **_controlfp** affect the control words for both the x87 and the SSE2, if present.
84+
85+
The function **__control87_2** enables both the x87 and SSE2 floating-point units to be controlled together or separately. To affect both units, pass in the addresses of two integers to **x86_cw** and **sse2_cw**. If you only want to affect one unit, pass in an address for that parameter, but pass in 0 (**NULL**) for the other. If 0 is passed for one of these parameters, the function has no effect on that floating-point unit. It's useful when part of your code uses the x87 floating-point unit, and another part uses the SSE2 floating-point unit.
86+
87+
If you use **__control87_2** to set different values for the floating-point control words, then **_control87** or **_controlfp** might be unable to return a single control word to represent the state of both floating-point units. In such a case, these functions set the **EM_AMBIGUOUS** flag in the returned integer value to indicate an inconsistency between the two control words. The **EM_AMBIGUOUS** flag is a warning that the returned control word might not represent the state of both floating-point control words accurately.
8688

87-
On the ARM and x64 architectures, changing the infinity mode or the floating-point precision is not supported. If the precision control mask is used on the x64 platform, the function raises an assertion and the invalid parameter handler is invoked, as described in [Parameter Validation](../../c-runtime-library/parameter-validation.md).
89+
On the ARM, ARM64, and x64 platforms, changing the infinity mode or the floating-point precision isn't supported. If the precision control mask is used on the x64 platform, the function raises an assertion, and the invalid parameter handler is invoked, as described in [Parameter Validation](../../c-runtime-library/parameter-validation.md).
8890

8991
> [!NOTE]
90-
> **__control87_2** is not supported on the ARM or x64 architectures. If you use **__control87_2** and compile your program for the ARM or x64 architectures, the compiler generates an error.
92+
> **__control87_2** is not supported on the ARM, ARM64, or x64 platforms. If you use **__control87_2** and compile your program for the ARM, ARM64, or x64 platforms, the compiler generates an error.
9193
92-
These functions are ignored when you use [/clr (Common Language Runtime Compilation)](../../build/reference/clr-common-language-runtime-compilation.md) to compile because the common language runtime (CLR) only supports the default floating-point precision.
94+
These functions are ignored when you use [/clr (Common Language Runtime Compilation)](../../build/reference/clr-common-language-runtime-compilation.md) to compile. The common language runtime (CLR) only supports the default floating-point precision.
9395

94-
**Hexadecimal Values**
96+
### Control word masks and values
9597

9698
For the **_MCW_EM** mask, clearing the mask sets the exception, which allows the hardware exception; setting the mask hides the exception. If a **_EM_UNDERFLOW** or **_EM_OVERFLOW** occurs, no hardware exception is thrown until the next floating-point instruction is executed. To generate a hardware exception immediately after **_EM_UNDERFLOW** or **_EM_OVERFLOW**, call the **FWAIT** MASM instruction.
9799

98100
|Mask|Hex value|Constant|Hex value|
99101
|----------|---------------|--------------|---------------|
100102
|**_MCW_DN** (Denormal control)|0x03000000|**_DN_SAVE**<br /><br /> **_DN_FLUSH**|0x00000000<br /><br /> 0x01000000|
101103
|**_MCW_EM** (Interrupt exception mask)|0x0008001F|**_EM_INVALID**<br /><br /> **_EM_DENORMAL**<br /><br /> **_EM_ZERODIVIDE**<br /><br /> **_EM_OVERFLOW**<br /><br /> **_EM_UNDERFLOW**<br /><br /> **_EM_INEXACT**|0x00000010<br /><br /> 0x00080000<br /><br /> 0x00000008<br /><br /> 0x00000004<br /><br /> 0x00000002<br /><br /> 0x00000001|
102-
|**_MCW_IC** (Infinity control)<br /><br /> (Not supported on ARM or x64] platforms.)|0x00040000|**_IC_AFFINE**<br /><br /> **_IC_PROJECTIVE**|0x00040000<br /><br /> 0x00000000|
104+
|**_MCW_IC** (Infinity control)<br /><br /> (Not supported on ARM or x64 platforms.)|0x00040000|**_IC_AFFINE**<br /><br /> **_IC_PROJECTIVE**|0x00040000<br /><br /> 0x00000000|
103105
|**_MCW_RC** (Rounding control)|0x00000300|**_RC_CHOP**<br /><br /> **_RC_UP**<br /><br /> **_RC_DOWN**<br /><br /> **_RC_NEAR**|0x00000300<br /><br /> 0x00000200<br /><br /> 0x00000100<br /><br /> 0x00000000|
104106
|**_MCW_PC** (Precision control)<br /><br /> (Not supported on ARM or x64 platforms.)|0x00030000|**_PC_24** (24 bits)<br /><br /> **_PC_53** (53 bits)<br /><br /> **_PC_64** (64 bits)|0x00020000<br /><br /> 0x00010000<br /><br /> 0x00000000|
105107

@@ -116,6 +118,7 @@ For more compatibility information, see [Compatibility](../../c-runtime-library/
116118
```C
117119
// crt_cntrl87.c
118120
// processor: x86
121+
// compile by using: cl /W4 /arch:IA32 crt_cntrl87.c
119122
// This program uses __control87_2 to output the x87 control
120123
// word, set the precision to 24 bits, and reset the status to
121124
// the default.
@@ -127,40 +130,38 @@ For more compatibility information, see [Compatibility](../../c-runtime-library/
127130
int main( void )
128131
{
129132
double a = 0.1;
130-
unsigned int control_word_x87;
133+
unsigned int control_word_x87 = 0;
134+
int result;
131135

132136
// Show original x87 control word and do calculation.
133-
control_word_x87 = __control87_2(0, 0,
134-
&control_word_x87, 0);
135-
printf( "Original: 0x%.4x\n", control_word_x87 );
137+
result = __control87_2(0, 0, &control_word_x87, 0 );
138+
printf( "Original: 0x%.8x\n", control_word_x87 );
136139
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
137140

138141
// Set precision to 24 bits and recalculate.
139-
control_word_x87 = __control87_2(_PC_24, MCW_PC,
140-
&control_word_x87, 0);
141-
printf( "24-bit: 0x%.4x\n", control_word_x87 );
142+
result = __control87_2(_PC_24, MCW_PC, &control_word_x87, 0 );
143+
printf( "24-bit: 0x%.8x\n", control_word_x87 );
142144
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
143145

144146
// Restore default precision-control bits and recalculate.
145-
control_word_x87 = __control87_2( _CW_DEFAULT, MCW_PC,
146-
&control_word_x87, 0 );
147-
printf( "Default: 0x%.4x\n", control_word_x87 );
147+
result = __control87_2( _CW_DEFAULT, MCW_PC, &control_word_x87, 0 );
148+
printf( "Default: 0x%.8x\n", control_word_x87 );
148149
printf( "%1.1f * %1.1f = %.15e\n", a, a, a * a );
149150
}
150151
```
151152
152153
```Output
153-
Original: 0x0001
154-
0.1 * 0.1 = 1.000000000000000e-002
155-
24-bit: 0x0001
156-
0.1 * 0.1 = 9.999999776482582e-003
157-
Default: 0x0001
158-
0.1 * 0.1 = 1.000000000000000e-002
154+
Original: 0x0009001f
155+
0.1 * 0.1 = 1.000000000000000e-02
156+
24-bit: 0x000a001f
157+
0.1 * 0.1 = 9.999999776482582e-03
158+
Default: 0x0009001f
159+
0.1 * 0.1 = 1.000000000000000e-02
159160
```
160161

161162
## See also
162163

163-
[Floating-Point Support](../../c-runtime-library/floating-point-support.md)<br/>
164-
[_clear87, _clearfp](clear87-clearfp.md)<br/>
165-
[_status87, _statusfp, _statusfp2](status87-statusfp-statusfp2.md)<br/>
166-
[_controlfp_s](controlfp-s.md)<br/>
164+
[Floating-Point Support](../../c-runtime-library/floating-point-support.md)\
165+
[_clear87, _clearfp](clear87-clearfp.md)\
166+
[_status87, _statusfp, _statusfp2](status87-statusfp-statusfp2.md)\
167+
[_controlfp_s](controlfp-s.md)

0 commit comments

Comments
 (0)