F# 中未抛出 System.ArithmeticException
考虑以下代码,
let a = 5. / 0.
let b = sin a
let c = sqrt(-5.)
它会产生 Infinity 和 NaN。在这两种情况下,我都希望抛出异常(出于调试目的)。
我使用 Visual Studio 2010。我将 Debug/Exceptions.../Common Language Runtime Exceptions/System/System.ArithmeticException 设置为“Thrown”,但是运行代码时,没有抛出异常。
知道为什么以及如何在 NaN 或 Infinity 上引发异常吗?
Consider the following code
let a = 5. / 0.
let b = sin a
let c = sqrt(-5.)
It produces both Infinity and NaN. In both cases I want to have an exception thrown (for debuging purposes).
I use Visual Studio 2010. I set up Debug/Exceptions.../Common Language Runtime Exceptions/System/System.ArithmeticException to "Thrown", but when running the code, no exception is thrown.
Any idea why and how to throw an exception on NaN or Infinity?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如其他人指出的,您必须明确检查 NaN 条件。如果您想使用一些高级 F# 功能来执行此操作,那么您还可以使用计算表达式。
可以定义一个构建器,在使用
let!
绑定值时自动检查 Nan。然后你可以写这样的内容:对于简单的检查来说,这可能太复杂了,但我发现它非常好。计算构建器的定义如下所示(您需要添加
While
、For
和其他一些来支持所有语言构造):As others noted, you'll have to check for the NaN condition explicitly. If you wanted to do this using some advanced F# features, then you could also use computation expressions.
It is possible to define a builder that automatically checks for Nan when you bind value using
let!
. Then you could write something like:This may be too complicated mechanism for just simple checks, but I find it quite nice. The definition of the computation builder looks like this (you'll need to add
While
,For
and some others to support all language constructs):如果您想要算术异常,请尝试将整数除以零。
System.Double
类型(F# 中的float
)在设计上不会引发异常(所有异常情况均以NaN
结束)。来自MSDN 文档:
更新:如果您希望在
Infinity
或NaN
的情况下抛出异常,我会提供 < a href="https://stackoverflow.com/questions/4782891/system-arithmeticexception-not-thron-in-f/4782960#4782960">与 desco 相同的建议并建议您包装您想要的方法称呼。不幸的是,我对 F# 不够熟悉,无法以您选择的语言提供代码示例;但在 C# 中,您可以对 sqrt 函数执行此操作:
更新 2:还有一个选择是为
double
类型本身编写自己的包装器,这不允许Infinity
或NaN
值(同样,下面是 C# - 如果这在 F# 中不可能,我很抱歉,在这种情况下,我给你的建议绝对没用):无论您在编写代码时不想允许
Infinity
或NaN
,都可以直接使用此类型,而不是直接使用double
。只是另一种选择。
If you want an arithmetic exception, try dividing an integer by zero. The
System.Double
type (float
in F#) by design does not throw exceptions (all exceptional circumstances end up atNaN
).From the MSDN docs:
Update: If you want exceptions to be thrown in cases of
Infinity
orNaN
, I would offer the same advice as desco and suggest you wrap the methods you want to call.Unfortunately, I'm not familiar enough with F# to give code examples in your language of choice; but in C# you might do this for example for a sqrt function:
Update 2: Yet another option would be to write your own wrapper for the
double
type itself which does not allowInfinity
orNaN
values (again, the below is C#—I apologize if this isn't possible in F# in which case I'm giving you absolutely useless advice):Then wherever you're writing code where you don't want to allow
Infinity
orNaN
, use this type rather thandouble
directly.Just another option.
认为,这只有通过在 sin\sqrt 上提供自定义包装器才有可能实现。当前行为记录为 Math.Sqrt 和 Math.Sin。
think, this is possible only by providing your custom wrappers over sin\sqrt. Current behavior is documented for Math.Sqrt and Math.Sin.