回 帖 发 新 帖 刷新版面

主题:求助: 怎样 提高 实型变量精度

写一个代码 

         PROGRAM MAIN
          REAL*8 A
          A=1.123456789123456789
          WRITE(*,*)A
          END

输出为 1.12345683575

说明在使用双精度时 只能保证7位有效数字。
但是我在实际工作中 至少需要10位以上的精度。 这该怎样处理?

回复列表 (共8个回复)

沙发

A = 1.123456789123456789D0

看来浮点数知识(缺乏)是一些同志永恒的“痛”。

板凳

A=1.123456789123456789_8

如果都需要10位以上高精度的话,最好在编译器中把浮点数的默认类型改为real8

3 楼

[quote]A = 1.123456789123456789D0

看来浮点数知识(缺乏)是一些同志永恒的“痛”。[/quote]

这个不说还真不知道,但是这个“浮点数知识”该怎么补习啊?

4 楼


没明白啥意思~ 您给多解释解释呗 
我要是很明白也不在这里问了

5 楼

加D就是双精度

没有D就是单精度

不像C语言默认为双精度

6 楼

[quote]
没明白啥意思~ 您给多解释解释呗 
我要是很明白也不在这里问了[/quote]
你给A指定了real(kind=8),但是没给1.123456789123456789指定是什么类型,因此系统按默认规矩来,给他制定real(kind=4)。如果给常量后面加上D就表示他是双精度,即real(kind=8),这时最少有15位有效数字。
多亏楼上几位大侠,我也多学到一些。

7 楼

我总结了下:

网上关于 浮点数数的解释:

浮点数型态 (REAL)
--------------------------------------------------------------------------------
real a 
未指定kind值时,通常宣告为单精准度(kind=4) 
单精准度 - 使用4字节(4 bytes, 32 bits) 
real(kind=4) a ! F90新增作法 
real(4)      b ! 
REAL*4       c ! F77传统作法 
可表示范围(PC):±1.18*10-38 ~ ±3.40*1038 
单精准度有效位数为6-7位,注意可能有以下问题:
a = 1000000. + 0.1 → a = 1000000. ← 常见错误,大数加小数! 
双精准度 - 使用4字节(8 bytes, 64 bits) 
real(kind=8) a ! F90新增作法 
real(8)      b ! 
REAL*8       c ! F77传统作法 
可表示范围(PC):±2.23*10-308 ~ ±1.79*10308 
双精准度有效位数为15位 
使用注意: 
可用科学记号表示法,如 
10,000,000,000 = 1E10 
0.0000000001 = 1E-10 
双精准度时请将E改为D,如1D10、1D-10 
常数部分请加上".0",如3 → 3.0(只加"."亦可) 
real a 
a= 1.5 + 3./2. → a= 3.0 (3.与2.被视为浮点数,以浮点数来记录结果) 
a= 1.5 + 3/2   → a= 2.5 (3/2视为整数,小数无条件舍去)← 常见错误! 
由于只要写成 3./2 就可以得到正确答案(分子或分母有一为实数),所以这里常有人以为「计算式中有一个变量或常数是实数就可以了」,其实不尽然对,比如在摄氏转华氏的问题中: 
1. Ft = Ct * 9/5 + 32 可得正确数字 
2. Ft = 9/5 * Ct + 32 会变成 Ft = 1*Ct + 32 
3. Ft = Ct*(9/5) + 32 也变成 Ft = Ct*1 + 32 
理由在于「算述运算子的优先次序」,第 2 式 9/5 先被计算,因为 9 和 5 都是整数,所得结果会被放入一个整数型态的计算缓存器,此时 9/5 便成为整数 1 ,而非正确的 1.8,再和 Ct 做乘法。 
第 3 式中,由于刮号内 9/5 优先被计算,所以也变成了 1 。 
许多FORTRAN编译器中,计算缓存器会以算式中需要位数最多的数值做为标准,所以 
1/3    → 1和3都是整数,以integer为计算缓存器配置(所以你才会得到1/3=0) 
1./3   → 1. 为 real*4 ,以 real*4 为计算缓存器配置 
1.d0/3 → 1.d0 为 real*8 ,以 real*8 为计算缓存器配置 
当然最好养成习惯,每个常数都改成正确的实数表示方法,而不要只偷懒改其中一个 
但CVF 6.5 并非如此,在测试中我们发现实数部分一律使用了 real*8 
有些FORTRAN编译器,不会看到上述的错误,比如其计算缓存器一律采用 REAL * 8 型态,则不会有上述因系统自行判断,使用了整数缓存器所产生的不预期结果。 
双精准度(REAL*8),常数请加上"d0",如3 → 3d0 或 3.d0 ← 常见忽略! 
a = 1/3     → a = 0.0000000000000000 
a = 1./3.   → a = 0.3333333432674408 
a = 1D0/3D0 → a = 0.3333333333333333 
"D"不分大小写,其意义同为科学记号表示法 
或采用 a = 1.0_4 表示 kind = 4    ! F90新增作法 
       a = 1.0_8 表示 kind = 8    ! F90新增作法



对于该贴这个问题:

#写一个代码 
#
#         PROGRAM MAIN
#          REAL*8 A
#          A=1.123456789123456789
#          WRITE(*,*)A
#          END
#输出为 1.12345683575

编译器的计算缓存器的配置默认应该是real*4
虽然A为双精度型 但是编译器会把1.123456789123456789当做单精度处理。
因此,A的赋值会发生变化。

因此 正常我们做加减乘除的时候 表达式中的实型常数会被当做单精度处理
比方:

#
#         PROGRAM MAIN
#          REAL*8 A
#          A=1.123456789123456789*1.0
#          WRITE(*,*)A
#          END

A的值相当于两个单精度数的计算结果。
要得到双精度的结果 
表达式要变为
A=1.123456789123456789D0*1.0D0

8 楼

编写一个函数,用指针作为参数,分别得到双精度实型数据的整数部分和小数部分的相关内容

我来回复

您尚未登录,请登录后再回复。点此登录或注册