繁体   English   中英

在 fortran 中将 Double 转换为 Real 时出现舍入错误

[英]Rounding error when converting Double to Real in fortran

我正在尝试将某些操作的双精度转换为实数,但我注意到一个错误。 我有一个用于阅读的宏, short是 4 个字节, long是 8 个字节。

这是执行代码:

print*, x, real(x, kind=short) 
print*, x*2.0, real(x*2.0, kind=short) 

print*, real( real(x, kind=short), kind=long) 
print*, real( real(x*2.0, kind=short), kind=long)

这打印出来:

173.43304556187957 173.433044 
346.86609112375913 346.866089

173.43304443359375 
346.86608886718750 

所以首先为什么我在转换为真实然后又回来之后还有任何价值? 不应该是173.43304400000000之类的东西吗? 当我转换它们时,为什么我的价值观会发生变化? 我该如何改变呢?

有关信息,fortran 2003,用 gfortran 编译,但我认为我们在使用 ifort 时遇到了同样的问题。

谢谢

不,不应该。 这些值存储为二进制(以 2 为底)浮点数,双精度的额外小数位是二进制零,而不是十进制零。 大多数十进制分数不能完全转换为二进制(反之亦然)。

当您以十六进制格式显示值时,您可以更好地了解正在发生的事情。 我使用了这个程序:

integer, parameter :: short = kind(0.0)
integer, parameter :: long = kind(0.0D0)
real(short) :: r4
real(long) :: r8

r8 = 173.43304556187957_long
print '(G0.16,1X,Z16.16)', r8,r8
r4 = r8
print '(G0.16,1X,Z8.8)',r4, r4
r8 = r4
print '(G0.16,1X,Z16.16)', r8,r8
end

当我运行它时,我得到:

173.4330455618796 4065ADDB825DBE6C
173.4330444335938 432D6EDC
173.4330444335938 4065ADDB80000000

请注意,重新转换为“long”只是添加二进制零,而不是更改值。 顺便说一句,使用列表导向格式可能会掩盖诸如此类的细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM