Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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
List 如何解决列表中的浮点数出错[haskell]_List_Haskell_Floating Point - Fatal编程技术网

List 如何解决列表中的浮点数出错[haskell]

List 如何解决列表中的浮点数出错[haskell],list,haskell,floating-point,List,Haskell,Floating Point,可能重复: 例如,当我输入 [0.1, 0.3 ..1] 我明白了: [0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999] 我期望: [0.1,0.3,0.5,0.7,0.9] 试一试 相反 问题是浮点数使用二进制分数,而二进制分数不能精确表示十进制分数。因此,您会得到错误,并且错误会不断累积 二进制分数不能精确地表示1/5,就像十进制分数不能精确地表示1/3一样——我们能做的最好的是0.33333 [0.1,0.3..1]是

可能重复:

例如,当我输入

[0.1, 0.3 ..1]
我明白了:

[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
我期望:

[0.1,0.3,0.5,0.7,0.9]
试一试

相反


问题是浮点数使用二进制分数,而二进制分数不能精确表示十进制分数。因此,您会得到错误,并且错误会不断累积

二进制分数不能精确地表示1/5,就像十进制分数不能精确地表示1/3一样——我们能做的最好的是0.33333

[0.1,0.3..1]

[0.1,
 0.1 + 0.2,
 0.1 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2]

另一个问题是,当下一个元素超过限制的一半时,列表将在等于或超过限制的第一个元素之后停止,这就是为什么有
1.099999999999999
元素。

试试看

相反


问题是浮点数使用二进制分数,而二进制分数不能精确表示十进制分数。因此,您会得到错误,并且错误会不断累积

二进制分数不能精确地表示1/5,就像十进制分数不能精确地表示1/3一样——我们能做的最好的是0.33333

[0.1,0.3..1]

[0.1,
 0.1 + 0.2,
 0.1 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2 + 0.2,
 0.1 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2]


另一个问题是,当下一个元素超过极限的一半时,列表将在等于或超过极限的第一个元素之后停止,这就是为什么有
1.099999999999999
元素。

这是计算机中浮点数的表示方式问题。带有浮点数的简单算术运算通常不符合预期。重复的算术运算会累积“舍入误差”,这意味着当你重复添加数字时,结果会越来越差(例如)

在某些情况下,可以通过使用不同的数值表示来避免这些问题。例如,如果您只关心有理数,那么可以使用
rational
类型。所以你可以做:

[0.1,0.3..1] :: [Rational]
其结果是:

[1 % 10,3 % 10,1 % 2,7 % 10,9 % 10,11 % 10]
这是正确答案,没有舍入误差;每个数字仅表示为两个
Integer
s的比率。根据您的具体情况,这可能是比使用浮点数更好的选择

这仍然超出了上限,但这比从浮点数得到的舍入误差更容易处理


请注意,对于某些性能关键型浮点数可能会更快。

这是一个浮点数在计算机中如何表示的问题。带有浮点数的简单算术运算通常不符合预期。重复的算术运算会累积“舍入误差”,这意味着当你重复添加数字时,结果会越来越差(例如)

在某些情况下,可以通过使用不同的数值表示来避免这些问题。例如,如果您只关心有理数,那么可以使用
rational
类型。所以你可以做:

[0.1,0.3..1] :: [Rational]
其结果是:

[1 % 10,3 % 10,1 % 2,7 % 10,9 % 10,11 % 10]
这是正确答案,没有舍入误差;每个数字仅表示为两个
Integer
s的比率。根据您的具体情况,这可能是比使用浮点数更好的选择

这仍然超出了上限,但这比从浮点数得到的舍入误差更容易处理


请注意,对于某些性能关键的浮点数可能会更快。

表达式
[e1,e2..e3]
的计算结果为
enumfromthen到e1 e2 e3
,这对于浮点数意味着(从):

对于Float和Double,上面Int的规则给出了enumFrom族的语义,但当元素大于正增量i的
e3+i/2
或小于负增量i的
e3+i/2
时,列表终止


这意味着,对于浮点数,
[e1,e2..e3]
的最后一个元素通常大于
e3
,并且可以高达
e3+(e2-e1)/2-ε

表达式
[e1,e2..e3]
的计算结果为
enumFromThenTo e1 e2 e3
,这对于浮点数意味着(from):

对于Float和Double,上面Int的规则给出了enumFrom族的语义,但当元素大于正增量i的
e3+i/2
或小于负增量i的
e3+i/2
时,列表终止


这意味着,对于浮点数,
[e1,e2..e3]
的最后一个元素通常大于
e3
,并且可以达到
e3+(e2-e1)/2-ε

读,我可以理解0.89999,因为浮点数不能精确表示。但是为什么生成的列表的值1.099999超过了值1。但是[1,3..10]会导致[1,3,5,7,9]。没有值11,这是第一个超过限制的元素。@RolandXu
Double
的真正规则是它将一直持续到数字超过结束条件的一半。比较一下
[1,4..6]:[Int]
[1,4..6]:[Double]
,和
[1.6,4.6..6]::[Double]
。这是Haskell规范中的一个bug,由一些好心的人引入。让最后一个元素超过上限是完全错误的,IMO.
map((/10).fromInteger)[1,3..10]
会更健壮。我可以理解0.89999,因为浮点不能精确表示。但是为什么生成的列表的值1.099999超过了值1。但是[1,3..10]会导致[1,3,5,7,9]。没有值11,这是第一个超过限制的元素。@RolandXu
Double
的真正规则是它将一直持续到数字超过结束条件的一半。比较
[1,4..6]