我知道浮点数学最多可能是丑陋的,但我想知道是否有人可以解释以下的怪癖.在我测试的大多数编程语言中,0.4到0.2的加法给出了轻微的误差,其中0.4 + 0.1 + 0.1给出了非.
是什么原因导致计算的不平等以及可以在各自的编程语言中采取哪些措施来获得正确的结果.
在python2/3中
.4 + .2
0.6000000000000001
.4 + .1 + .1
0.6
Run Code Online (Sandbox Code Playgroud)
Julia 0.3也是如此
julia> .4 + .2
0.6000000000000001
julia> .4 + .1 + .1
0.6
Run Code Online (Sandbox Code Playgroud)
和斯卡拉:
scala> 0.4 + 0.2
res0: Double = 0.6000000000000001
scala> 0.4 + 0.1 + 0.1
res1: Double = 0.6
Run Code Online (Sandbox Code Playgroud)
和哈斯克尔:
Prelude> 0.4 + 0.2
0.6000000000000001
Prelude> 0.4 + 0.1 + 0.1
0.6
Run Code Online (Sandbox Code Playgroud)
但是R v3是正确的:
> .4 + .2
[1] 0.6
> .4 + .1 + .1
[1] 0.6
Run Code Online (Sandbox Code Playgroud) 对于我的一个项目,我已经实现了一个基于的枚举
trait Enum[A] {
trait Value { self: A =>
_values :+= this
}
private var _values = List.empty[A]
def values = _values
}
sealed trait Currency extends Currency.Value
object Currency extends Enum[Currency] {
case object EUR extends Currency
case object GBP extends Currency
}
Run Code Online (Sandbox Code Playgroud)
来自Case对象与Scala中的枚举.我工作得很好,直到遇到以下问题.Case对象似乎很懒惰,如果我使用Currency.value,我可能实际上得到一个空列表.可以在启动时对所有枚举值进行调用,以便填充值列表,但这将有点击败这一点.
因此,我冒险进入scala反射的黑暗和未知的地方,并根据以下SO答案提出了这个解决方案.我是否可以获得所有案例对象的编译时列表,这些案例对象派生自Scala中的密封父代? 和我怎样才能获得通过斯卡拉2.10反射提到了实际的对象?
import scala.reflect.runtime.universe._
abstract class Enum[A: TypeTag] {
trait Value
private def sealedDescendants: Option[Set[Symbol]] = {
val symbol = typeOf[A].typeSymbol
val internal = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol]
if (internal.isSealed)
Some(internal.sealedDescendants.map(_.asInstanceOf[Symbol]) - symbol) …Run Code Online (Sandbox Code Playgroud)