使用双精度幻数时的最佳实践 [英] Best practice when working with double precision magic numbers

查看:9
本文介绍了使用双精度幻数时的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是否必须在所有 幻数(字面常量)如果我已经声明所有内容都是双精度的?

Do I necessarily need to specify D (e.g., 1.234D+00) at the end of all magic numbers (literal constants) if I've already declared everything double precision anyway?

推荐答案

简短回答:是的,你可以.

Short answer: Yes, you do.

长答案:默认情况下,除非另有说明,否则真正的文字是单精度的.将单精度文字分配给双精度变量会导致精度损失;也就是说,单精度文字首先被评估为单精度,然后分配给更高精度的变量.我懒得从另一个房间取回 F2003 手册,但我怀疑单到双分配将低有效尾数位设置为零.要么,要么由供应商决定.

Long answer: By default, real literals are single precision unless otherwise specified. Assigning single precision literals to double precision variables incurs precision loss; that is, single precision literals are evaluated first as single precision then assigned to the higher-precision variable. I'm too lazy to retrieve the F2003 Handbook from the other room but I suspect that single-to-double assignment sets the low significance mantissa bits to zero. Either that or it's left up to the vendor.

不管怎样,这里演示了在文字和变量之间混合精度时会发生什么(注意 0.1 不能干净地存储在二进制浮点中):

Regardless, here's a demonstration of what happens when you mix precision between literals and variables (note that 0.1 can't be stored cleanly in binary floating point):

!> Demonstrate the effects of D and E suffixes on precision of literals
program whatkind
    use iso_fortran_env, only: output_unit, REAL32, REAL64
    implicit none

    real (kind=REAL64) :: dtest

10 format('Literal ', A, ' is of kind ', I2)
20 format(/, A)
30 format(/, 'Value stored in ', A, ' precision generated with ', A,    &
          ' precision literals:')
40 format('Literal is ', A)

    continue

    write(output_unit, 10) '1.0', kind(1.0)
    write(output_unit, 10) '1.0E0', kind(1.0E0)
    write(output_unit, 10) '1.0D0', kind(1.0D0)
    write(output_unit, 10) '1.0_REAL32', kind(1.0_REAL32)
    write(output_unit, 10) '1.0_REAL64', kind(1.0_REAL64)

    write(output_unit, 20) 'Raw tenths tests:'

    dtest = 0.1
    write(output_unit, 30) 'double', 'single'
    write(output_unit, 40) '0.1'
    write(output_unit, *) dtest

    dtest = 0.1D0
    write(output_unit, 30) 'double', 'double'
    write(output_unit, 40) '0.1D0'
    write(output_unit, *) dtest

    dtest = 1.0 / 10.0
    write(output_unit, 30) 'double', 'single'
    write(output_unit, 40) '0.1'
    write(output_unit, 40) '1.0 / 10.0'
    write(output_unit, *) dtest

    dtest = 1.0_REAL64 / 10.0_REAL64
    write(output_unit, 30) 'double', 'double'
    write(output_unit, 40) '1.0_REAL64 / 10.0_REAL64'
    write(output_unit, *) dtest

    dtest = 1.0_REAL32 / 10.0_REAL32
    write(output_unit, 30) 'double', 'single'
    write(output_unit, 40) '1.0_REAL32 / 10.0_REAL32'
    write(output_unit, *) dtest

    dtest = 1.0_REAL64 / 10.0_REAL32
    write(output_unit, 30) 'double', 'mixed'
    write(output_unit, 40) '1.0_REAL64 / 10.0_REAL32'
    write(output_unit, *) dtest

    dtest = 1.0_REAL32 / 10.0_REAL64
    write(output_unit, 30) 'double', 'mixed'
    write(output_unit, 40) '1.0_REAL32 / 10.0_REAL64'
    write(output_unit, *) dtest

end program whatkind

这样的结果是:

Literal 1.0 is of kind  4
Literal 1.0E0 is of kind  4
Literal 1.0D0 is of kind  8
Literal 1.0_REAL32 is of kind  4
Literal 1.0_REAL64 is of kind  8

Raw tenths tests:

Value stored in double precision generated with single precision literals:
Literal is 0.1
  0.10000000149011612     

Value stored in double precision generated with double precision literals:
Literal is 0.1D0
  0.10000000000000001     

Value stored in double precision generated with single precision literals:
Literal is 0.1
Literal is 1.0 / 10.0
  0.10000000149011612     

Value stored in double precision generated with double precision literals:
Literal is 1.0_REAL64 / 10.0_REAL64
  0.10000000000000001     

Value stored in double precision generated with single precision literals:
Literal is 1.0_REAL32 / 10.0_REAL32
  0.10000000149011612     

Value stored in double precision generated with mixed precision literals:
Literal is 1.0_REAL64 / 10.0_REAL32
  0.10000000000000001     

Value stored in double precision generated with mixed precision literals:
Literal is 1.0_REAL32 / 10.0_REAL64
  0.10000000000000001 

您会看到,在所有文字都是单精度的情况下(包括那些没有明确设置精度的文字),双精度变量中存储的噪音"意义不大.

You see how in cases where all the literals are single precision (including those with no explicit precision set) there is low significance 'noise' stored in the double precision variable.

我发现有趣的是,在执行操作之前,对混合精度文字的操作似乎会将所有文字提升到更高的精度.有更多语言规范的人可能能够解释这一点.

I find it interesting that operations on mixed precision literals seems to promote all the literals to higher precision before the operation is performed. Someone with more language-spec-fu might be able to explain that.

我的建议:如有疑问,请明确表示.它更安全,我认为额外的按键是值得的.

My advice: When in doubt, be explicit. It's safer and I think it's worth the extra keystrokes.

这篇关于使用双精度幻数时的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆