如何在 VBA Excel 中保持高小数精度
How to maintain high decimal precision in VBA Excel
我正在转换至少保持 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
Z = (X * Y) / Tan(0#)
0
文字上的类型提示是多余的,Tan
函数接受一个 Double
和 returns 一个 Double
。但是 Tan(0)
returns 0
,所以你 是 除以 0
.
您的在线 Fortran 编译器似乎在做一些奇怪的事情。
it should not be zero tho, it should be tan(1E-16)
没有。这在数学上是错误的,VBA 是正确的。如果您需要您的 VBA 代码像 Fortran 一样损坏,那么您需要明确地处理这种情况:
Z = (X * Y) / Tan(1E-16)
但只知道这在数学上是错误的。我不知道 Fortran 代码如何设法输出 1.5707963267948966
。此 VBA 代码输出 3.90580528128931E+16
.
无需过多赘述,Fortran 可以支持 +/- Infinity 和 NaN 的实数值(浮点数),具体取决于值的计算方式。例如,您的原始 post 包含两个未初始化的变量,您随后将其用于计算 (v1 * v2)/dtan(0.0d0)
。由于未初始化的变量通常(但不总是)设置为 0,因此此计算变为 0.0/0.0
,这在数学上是未定义的,结果为 NaN
.1
现在,如果分子为正,则 z=(x*y)/dtan(0.0D0)
结果为 z=Infinity
,而不管 x
和 y
是什么。如果您的系统不能表示 Infinity,则它使用 "a very large number"。 VBA.
显然就是这种情况
最后,你计算datan(.04D0*z)
。在数学上,这是 arctangent(Infinity)=PI/2。同样,正确计算的 Fortran 结果与此匹配,返回双精度值 1.57079632679490
.2
现在,我不太了解VBA,但它似乎不支持+/-Infinity 或NaN。如果 "very large number" 导致与您在最终结果中预期的结果相比出现重大错误,那么似乎有 this SO question.
中所述的解决方法
1 请注意,在具有双精度的 Fortran 中,您应该得到 dtan(0.0d0) = 0.000000000000000E+000
.
2
为了在 Fortran x
和 y
变量中保持双精度,您 必须 追加 d0
。否则默认情况下它们将成为单精度值,并且仅存储原始分配的前 7 个 sig figs,而双精度值中的其余数字采用什么由编译器决定(通常只是垃圾)。
我正在转换至少保持 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
Z = (X * Y) / Tan(0#)
0
文字上的类型提示是多余的,Tan
函数接受一个 Double
和 returns 一个 Double
。但是 Tan(0)
returns 0
,所以你 是 除以 0
.
您的在线 Fortran 编译器似乎在做一些奇怪的事情。
it should not be zero tho, it should be tan(1E-16)
没有。这在数学上是错误的,VBA 是正确的。如果您需要您的 VBA 代码像 Fortran 一样损坏,那么您需要明确地处理这种情况:
Z = (X * Y) / Tan(1E-16)
但只知道这在数学上是错误的。我不知道 Fortran 代码如何设法输出 1.5707963267948966
。此 VBA 代码输出 3.90580528128931E+16
.
无需过多赘述,Fortran 可以支持 +/- Infinity 和 NaN 的实数值(浮点数),具体取决于值的计算方式。例如,您的原始 post 包含两个未初始化的变量,您随后将其用于计算 (v1 * v2)/dtan(0.0d0)
。由于未初始化的变量通常(但不总是)设置为 0,因此此计算变为 0.0/0.0
,这在数学上是未定义的,结果为 NaN
.1
现在,如果分子为正,则 z=(x*y)/dtan(0.0D0)
结果为 z=Infinity
,而不管 x
和 y
是什么。如果您的系统不能表示 Infinity,则它使用 "a very large number"。 VBA.
最后,你计算datan(.04D0*z)
。在数学上,这是 arctangent(Infinity)=PI/2。同样,正确计算的 Fortran 结果与此匹配,返回双精度值 1.57079632679490
.2
现在,我不太了解VBA,但它似乎不支持+/-Infinity 或NaN。如果 "very large number" 导致与您在最终结果中预期的结果相比出现重大错误,那么似乎有 this SO question.
中所述的解决方法1 请注意,在具有双精度的 Fortran 中,您应该得到 dtan(0.0d0) = 0.000000000000000E+000
.
2
为了在 Fortran x
和 y
变量中保持双精度,您 必须 追加 d0
。否则默认情况下它们将成为单精度值,并且仅存储原始分配的前 7 个 sig figs,而双精度值中的其余数字采用什么由编译器决定(通常只是垃圾)。