C/FORTRAN 将双下溢设置为零

Posted

技术标签:

【中文标题】C/FORTRAN 将双下溢设置为零【英文标题】:C/FORTRAN set double underflow to zero 【发布时间】:2015-04-13 08:46:15 【问题描述】:

我有一个遗留的 FORTRAN 项目,其中进行了一些非常密集的计算。我希望这个数学代码可以被 C/C++ 代码访问,所以我构建了一个 FORTRAN dll,将其导入 C/C++ 并开始从我的 FORTRAN dll 接收浮点下溢。

同时,如果我从 FORTRAN 应用程序调用 FORTRAN dll 代码,它也可以正常执行。

最后,我发现我使用的编译器(它是集成到 VS2013 中的 FTN 95)有一个选项 (/UNDERFLOW)。如果未指定此标志,则默认情况下所有下溢都转换为零。这发生在 FORTRAN 应用程序中。当我使用 C 代码执行此 dll 中的方法时,我收到下溢。

那么,问题是:有什么办法可以强制 VC++ 编译器将下溢转换为零?

P.S.:是的,我知道依赖一直抛出浮点异常的代码是愚蠢的。但是,这段代码很旧,目前不可能使用最新技术完全重写它。

【问题讨论】:

收到浮点下溢是什么意思?你得到一个异常,或一个非规范值或什么?此外,太小的数字并不一定意味着什么不好,它只是一个小幅度的数字,但它在数学上可能是正确的结果。您对 C++ 项目使用哪些编译器选项?是Debug模式还是Release模式? 当我使用导入的 FORTRAN dll 运行我的 C 代码时,有时应用程序崩溃并且内置的 VS 调试器通知我在我的 dll 中发生了未处理的异常;描述说它是浮点下溢。还提供了错误函数的地址。带有标志 (/UNDERFLOW) 的 FORTRAN 应用程序也会发生同样的情况。我想要告诉编译器我希望所有下溢都被视为零,没有断点/异常。 FORTRAN 编译器有这样的选项,而 VC++ 似乎没有。 好的,您查看手册了吗?我从未使用过 VC++,但我的谷歌显示这是第一次点击msdn.microsoft.com/en-us/library/e7s85ffb.aspx TLDR:试试/fp:except- 是的,我已经阅读了文档并尝试了几种方法 - 仍然没有。我知道这是由于我的狂野 FORT/C 互操作性造成的,但现在我很好奇。我不确定 fp 控件如何影响双精度,因为我的代码使用双精度并且异常本质上是双精度下溢。 是的,但我无意中找到了解决方案。问题不在于 C 代码,而在于构建 .dll 和 .exe 之间的 FORTRAN 编译器选项差异。我将在下面发布答案。无论如何,感谢您提供有关浮点厨房的有用链接和见解。 【参考方案1】:

所以,问题出在 FTN95 编译器上。上面提到的标志 (/UNDERFLOW) 似乎仅在构建应用程序时才有用。当目标输出为 DLL 时,忽略此标志的影响。而不是这个,我找到了一个编译器指令,它可以通过调用MASK_UNDERFLOW@() 子例程来访问。在引发下溢并重新编译 DLL 的 FORTRAN 函数中插入对该子例程的显式调用后,我成功地启动了 C 程序并使用 FORTRAN dll 中的函数执行必要的计算。此外,还使用了fp:/except- VC++ 编译器标志来确保没有其他下溢会影响 C 程序的执行。

【讨论】:

以上是关于C/FORTRAN 将双下溢设置为零的主要内容,如果未能解决你的问题,请参考以下文章

在混合 C/Fortran 代码中捕获浮点异常

c_cpp Fortran FLTK

FORTRAN & MATLAB 混合编程

当 Fortran 生成大型内部临时数组时,如何避免堆栈溢出?

如何编译C/Fortran动态/静态链接库

xmake v2.3.8 发布, 新增 Intel C++/Fortran 编译器支持