Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 给出奇异值的基本算法_Math_Fortran - Fatal编程技术网

Math 给出奇异值的基本算法

Math 给出奇异值的基本算法,math,fortran,Math,Fortran,我试图计算一个函数形式为x+10(y+10(z+10)(w+10(u+1000v ')))的值。假设x=y=z=w=1,u=3,v=2。那么这应该是20031111。我希望这是一个浮点数,而不是整数。当我使用代码时 output = x+10(y+10(z+10(w+10(u+1000v))))) 我得到了预期的20031111。然而,当我使用 output = 1.0(x+10(y+10(z+10(w+10(u+1000v)))))) 我得到20031112.000,这是错误的。这是怎么回

我试图计算一个函数形式为x+10(y+10(z+10)(w+10(u+1000v ')))的值。假设x=y=z=w=1,u=3,v=2。那么这应该是20031111。我希望这是一个浮点数,而不是整数。当我使用代码时

output = x+10(y+10(z+10(w+10(u+1000v)))))
我得到了预期的20031111。然而,当我使用

output = 1.0(x+10(y+10(z+10(w+10(u+1000v))))))
我得到20031112.000,这是错误的。这是怎么回事


顺便说一下,如果我用1.D0而不是1.0预乘,我会再次得到正确的答案。但我不明白为什么。

浮点数是实数。Fortran中的默认实数类型不能精确地表示具有8个有效algarism的数字。值的最佳近似值将存储在变量中,在您的情况下,它是
2.0031112E+07

您可以执行以下测试:

real :: output
integer :: x = 1, y = 1, z = 1, w = 1, u = 3, v = 2
! (...)
output = 1.0 *(x + 10 *(y + 10 * (z + 10 * (w + 10 * (u + 1000 * v)))))
print*, output + 2   ! prints: 2.0031114+07
print*, output + 1   ! prints: 2.0031112+07
print*, output       ! prints: 2.0031112+07
print*, output - 1   ! prints: 2.0031112+07
print*, output - 2   ! prints: 2.0031110+07
作为一种解决方案,您必须使用一个实数类型和一个能够以您想要的精度表示数据的种类参数。Fortran提供了一个内在函数,可以帮助您选择符合精度的最小类型,
选定的\u real\u种类

例如:

integer, parameter :: wp = selected_real_kind(8) ! 8 precision digits
real(wp) :: output    ! <- here you use wp as the kind parameter
integer :: x = 1, y = 1, z = 1, w = 1, u = 3, v = 2
! (...)
! you can also apply the kind parameter to litreals as below, like 1.0_wp
output = 1.0_wp *(x + 10 *(y + 10 * (z + 10 * (w + 10 * (u + 1000 * v)))))
print*, output + 2   ! prints: 20031113.0000000
print*, output + 1   ! prints: 20031112.0000000
print*, output       ! prints: 20031111.0000000
print*, output - 1   ! prints: 20031110.0000000
print*, output - 2   ! prints: 20031109.0000000
integer,参数::wp=selected\u real\u kind(8)!8个精确数字

真实(wp)::输出 在浮点表示法中,您达到了可表示整数的极限

通过将结果与
1.0
相乘,可以将结果转换为默认的
REAL
,并且只有少数整数可以用这样的数字精确表示

从不声明任何类型的
REAL
都应该表示一个。
REAL
的表示取决于处理器。尽管如此,最常见的代表是IEEE-754。为此,我们假设您的类型
REAL
是一种单精度浮点格式

在此格式中,可以精确表示范围
[-1677721616777216]
中的整数。此数字类似于
2**24
(23位小数部分和额外的默认值1)

1.0D0
相乘时,您将整数转换为
双精度
数字,最常用的表示形式是双精度浮点格式。在这里,您可以表示范围
[-90071992547409929007199254740992]
中的所有整数


如您所见,数字
20031111
不在表示的范围内,因此是近似的,而它在表示的范围内。

我无法重现您的1.D0结果,但它可能取决于所使用的编译器的舍入方法。现在不是所有的Fortran编译器都支持IEEE 754吗?我明白了,但是即使在1.0中包含了_wp,您的示例仍然得到了错误的值。怎么回事?@F.User,答案很好,我只是打错了。现在它被更正了。@johncampbell,事实上,如果您将它存储回一个默认的实数类型变量,那么精度就会丢失。我想OP测试了它直接将结果表达式打印到屏幕上,而不存储-在本例中,打印了一个
双精度
值。谷歌是你的朋友。