将单精度 float 转换为 double 以进行除法

标签 c floating-point fortran hpc

作为一名高性能计算人员,我们倾向于尽可能默认使用单精度 float (floatreal)。这是因为如果每个操作单独执行得更快,您每秒可以执行更多操作。

然而,与我共事的一位资深人士始终坚持(当需要准确性时)您应该暂时将单精度数据转换为 double 据,以便执行除法。即:

float a, b;
float ans = ((double)a)/((double)b);

real :: a, b, ans
ans = real(dble(a)/dble(b))

取决于您使用的语言。在我看来,这看起来真的很难看,老实说,我什至不知道 ans 中的答案是否比如果您只是简单地以单点精度编写 ans = a/b

谁能告诉我在算术之前转换你的数字,特别是为了执行除法,是否真的会得到更准确的答案?这是一个语言/编译器特定的问题,还是由 IEEE 决定?这种准确度提高在什么数值下最为显着?

任何有启发性的评论/答案将不胜感激。

最佳答案

float ans = ((double)a)/((double)b);

article演示 ans 始终与 IEEE 754 算术和 FLT_EVAL_METHOD=0 的单精度除法计算的结果相同。

当 FLT_EVAL_METHOD=1 时,同样的属性也同样成立。

当FLT_EVAL_METHOD=2时,我不确定。可能有人会将规则解释为 a/blong double 计算必须首先四舍五入为 double,然后为 float 。在这种情况下,它可能不如直接从 long double 舍入到 float 准确(后者产生正确舍入的结果,而前者可能在极度情况下无法这样做极少数情况,除非另一个像菲格罗亚的定理适用并表明这永远不会发生)。

长话短说,对于任何现代合理的浮点计算平台 (*),float ans = ((double)a)/((double)b​​); 具有迷信任何好处。你应该让你在问题中提到的资深人士展示一对 a, b 结果不同的值,更不用说更准确了。当然,如果他们坚持认为这样更好,那么提供一对值对他们来说应该没有问题,因为它会有所作为。

(*) 记得在 GCC 中使用 -fexcess-precision=standard 以保持理智

关于将单精度 float 转换为 double 以进行除法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31351631/

相关文章:

c++ - 如果两个数据之间的不变量必须在所有线程上保持不变,它是否会强制对这些数据的读/写处于临界区?

c - C 中围绕字符分割字符串

python - 指数位数

ios - 为什么从 UITextField 输入的字符串中四舍五入到较低的整数?

fortran - PBS 工作和 Fortran

c - Fortran 和 C 混合编程(共享内存)

c - 将 char* 传递给需要 unsigned char* 的方法

c - C 程序中的陷阱命令?

c# - 在C#中检查浮点变量的确切值相等的正确方法是什么?

debugging - 从 VB6.0 调用时,DLL 中的 Fortran `read(*,*)` 会导致 "run time error(39)"