【问题标题】:How to maintain high decimal precision in VBA Excel如何在 VBA Excel 中保持高小数精度
【发布时间】:2018-01-20 04:25:18
【问题描述】:

我正在转换一个至少保持 16 位小数精度的 FORTRAN 代码。 我在 VBA excel 中遇到了除以零的问题,但是如果我在 this online compiler 上尝试下面的代码,我不会得到零。 任何帮助表示赞赏。提前致谢。

这是fortran代码

program sum
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
x = 3.14159265358979
y = 1.24325643454325

z = (x*y)/dtan(0.0D0) 
print *, datan(.04D0*z)
end program sum

这是 VBA 代码

Public Function dosomething()
Dim X As Double
Dim Y As Double
Dim Z As Double
X = 3.14159265358979
Y = 1.24325643454325
Z = (X * Y) / Tan(0#)
End Function

【问题讨论】:

  • 这看起来不像 VBA 代码。如果您希望 VBA 人员提供帮助,介意分享实际的 VBA 代码吗?
  • 这是 Fortran 代码,如果我在 Fortran 在线编译器上尝试它可以工作,但如果我在 VBA 中尝试它就不起作用。
  • 0 的切线是0,所以你要除以0,因此会出现错误。
  • 但您的代码显示 Tan(0) 而不是 Tan(1E-16)。所以把它放进去,你就不会再收到divided by 0 错误了。
  • 请注意,要在 xy 变量中保持双精度,您必须将指示符 d0 附加到数字后,如 x=3.14159265358979d0。这是一个常见的错误。如果不这样做,编译器通常会假定变量是单精度的,并且仅保留原始赋值的前 7 位数字。

标签: vba excel fortran fortran77


【解决方案1】:

无需赘述,Fortran 可以支持 +/-Infinity 和 NaN 的实数值(浮点数),具体取决于数值的计算方式。例如,您的原始帖子包含两个未初始化的变量,然后您使用它们来计算 (v1 * v2)/dtan(0.0d0)。由于未初始化的变量通常(但不总是)设置为 0,因此该计算变为 0.0/0.0,在数学上未定义,结果为 NaN1

现在,如果分子是正数,z=(x*y)/dtan(0.0D0) 的结果是 z=Infinity,而不管 xy 是什么。如果您的系统不能代表 Infinity,那么它使用“非常大的数字”。 VBA 显然就是这种情况。

最后,您计算datan(.04D0*z)。在数学上,这是 arctangent(Infinity)=PI/2。同样,正确计算的 Fortran 结果与此匹配,返回双精度值 1.570796326794902

现在,我对 VBA 了解不多,但它似乎不支持 +/-Infinity 或 NaN。如果与您对最终结果的预期相比,“非常大的数字”导致了重大错误,那么似乎有this SO question 中所述的解决方法。


1请注意,在双精度的 Fortran 中,您应该得到 dtan(0.0d0) = 0.000000000000000E+000

2 为了在 Fortran xy 变量中保持双精度,您必须附加 d0。否则,默认情况下它们将成为单精度值,并且仅存储原始分配中的前 7 个 sig 无花果,而双精度值中剩余的数字将由编译器决定(通常只是垃圾)。

【讨论】:

    【解决方案2】:
    Z = (X * Y) / Tan(0#)
    

    0 文字上的类型提示是多余的,Tan 函数接受 Double 并返回 Double。但是Tan(0) 返回0,所以你正在除以0

    您的在线 Fortran 编译器似乎正在做一些时髦的事情。

    它不应该是零,应该是 tan(1E-16)

    没有。这在数学上是错误的,VBA 做得对。如果你需要你的 VBA 代码和 Fortran 一样被破坏,那么你需要明确地处理这种情况:

    Z = (X * Y) / Tan(1E-16)
    

    但只要知道这在数学上是错误的。我不知道 Fortran 代码如何输出1.5707963267948966。此 VBA 代码输出 3.90580528128931E+16

    【讨论】:

    • 谢谢。我知道这在数学上是不可能的,但我潜伏了你的个人资料,看起来你对 VBA 很满意。 fortran 中的代码将变量设置为等于 0.0D0,当我在 VBA 中键入它时,它会将其更改为 0#,不确定这意味着什么。我假设 0# 相当于 fortran 中的 0.0D0,这就是错误所在。
    • 0# 是一个type-hinted Double literal,其值为0。 BASIC 起源于 FORTRAN(早在它获得“视觉”之前),这就是 D 的自动更正的来源。我不知道 0.0D0 在 FORTRAN 中除了 0 之外的任何东西。
    • OP 显示的 Fortran 代码存在一些问题,但正确的数学结果确实是 PI/2 或双精度约 1.57079632679490。这是因为datan(.04D0*z) 等价于反正切(Infinity)。
    • 显然,您的 vba 代码与 Fortran 单精度和双精度的任意外观混合不匹配。您显示 x 和 y 初始化的单精度。
    • @tim18,如果我用 D0 附加变量,它仍然不会改变结果。我对 z = (x*y)/dtan(0.0D0) 等于无穷大而不是零的部分感到困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    相关资源
    最近更新 更多