【发布时间】:2013-09-19 15:01:24
【问题描述】:
我有一个很长很复杂的源代码,我需要找到将变量值设置为 nan 的确切位置。所以我需要编译器在那时抛出异常。 这个问题以前有人问过。我发现以下答案是一个很好的答案。此代码在 .net 3.5 中运行良好。但是当我使用 .net 4 时,此解决方案无法正常工作。即使我在调试器中启用“抛出异常时中断”,也无法在代码中找到异常。有什么想法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ConsoleApplication2
{
class Program
{
[System.Runtime.InteropServices.DllImport("msvcrt.dll")]
public static extern uint _control87(uint a, uint b);
[System.Runtime.InteropServices.DllImport("msvcrt.dll")]
public static extern uint _clearfp();
static void Main(string[] args)
{
float zero = 0.0f - args.Length; // Want 0.0f. Fool compiler...
System.Console.WriteLine("zero = " + zero.ToString());
// A NaN which does not throw exception
float firstNaN = zero / 0.0f;
System.Console.WriteLine("firstNaN= " + firstNaN.ToString());
// Now turn on floating-point exceptions
uint empty = 0;
uint cw = _control87(empty, empty); // Debugger halts on this one and complains about false signature, but continue works.
System.Console.WriteLine(cw.ToString());
uint MCW_EM = 0x0008001f; // From float.h
uint _EM_INVALID = 0x00000010; // From float.h (invalid corresponds to NaN
// See http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.html#x86_FP
cw &= ~(_EM_INVALID);
_clearfp(); // Clear floating point error word.
_control87(cw, MCW_EM); // Debugger halts on this one and complains about false signature, but continue works.
System.Console.WriteLine(cw.ToString());
// A NaN which does throw exception
float secondNaN = 0;
try
{
// Put as much code here as you like.
// Enable "break when an exception is thrown" in the debugger
// for system exceptions to get to the line where it is thrown
// before catching it below.
secondNaN = zero / 0.0f;
}
catch (System.Exception ex)
{
_clearfp(); // Clear floating point error word.
}
System.Console.WriteLine("secondNaN= " + secondNaN.ToString());
}
}
}
【问题讨论】:
-
你的问题是什么...编译时错误或吞下运行时错误?
-
@SimonWhitehead 我会说他想将信号 NaN 捕获为异常。
-
如果你想捕获所有个浮点异常,改变
uint _EM_INVALID = 0x0000001F;。请参阅_controlfp命令的文档。例如,捕捉Math.Log(0.0).