在 scala 中比较 Double 常量和 Double#equals 是否省事?
Is it save to compare Double constants with Double#equals in scala?
我正在编写一个代码,其中将双精度值与标记缺失值的预定义常量进行比较。如果变量不满足某些要求,则该值的使用方式是将其分配给变量(此处 input
):
val BAD = -9999.9
val verified = if(isQualityOk(input)) input else BAD
稍后在应用程序中再次检查数字是否正确:
if(!myNumber.equals(BAD)) {
// do something with it
}
我知道由于舍入误差(有限的机器精度),使用 "equals" 比较 Float/Double 值通常不是一个好主意,因此建议比较它们的绝对值差异在一定限度内。
我的问题:在我上面没有对数字进行算术运算的示例中,这是否也是必要的?或者在这种情况下使用 Double#equals
的实现是否安全?
如果没有计算,那么就没有地方可以丢失精度(从十进制数到二进制数的转换除外)。
所以你应该好好的。
话虽如此 - 由于您提到的响应,这种代码在未来的 2-3 个版本中会产生一些细微的错误,因此如果此代码将进入应保持可行的代码长 运行,我会重新安排使用更安全的数据类型(verified
听起来应该是 Boolean
,不是吗?)
如果你的 Double
没有进行浮点运算,应该没问题。
但是,这不是您在函数式编程中处理特殊情况的方式。
执行以下操作可能会更明确:
val verified: Option[Double] = Some(input).filter(isQualityOk)
这样类型系统会告诉您您不确定是否具有有效值(如果质量不佳,它将是 None
)。
如果您通常将函数 f(d: Double): T
应用于 verified
,只需执行 verified.map(f)
,以获得 Option[T]
,然后继续。
每当你需要一个真实的值时,你总是可以通过 verfied.getOrElse(BAD)
返回到 Double
,但最好将例外情况尽可能保持为 None
, 以便类型系统可以帮助您避免一些错误。
我正在编写一个代码,其中将双精度值与标记缺失值的预定义常量进行比较。如果变量不满足某些要求,则该值的使用方式是将其分配给变量(此处 input
):
val BAD = -9999.9
val verified = if(isQualityOk(input)) input else BAD
稍后在应用程序中再次检查数字是否正确:
if(!myNumber.equals(BAD)) {
// do something with it
}
我知道由于舍入误差(有限的机器精度),使用 "equals" 比较 Float/Double 值通常不是一个好主意,因此建议比较它们的绝对值差异在一定限度内。
我的问题:在我上面没有对数字进行算术运算的示例中,这是否也是必要的?或者在这种情况下使用 Double#equals
的实现是否安全?
如果没有计算,那么就没有地方可以丢失精度(从十进制数到二进制数的转换除外)。 所以你应该好好的。
话虽如此 - 由于您提到的响应,这种代码在未来的 2-3 个版本中会产生一些细微的错误,因此如果此代码将进入应保持可行的代码长 运行,我会重新安排使用更安全的数据类型(verified
听起来应该是 Boolean
,不是吗?)
如果你的 Double
没有进行浮点运算,应该没问题。
但是,这不是您在函数式编程中处理特殊情况的方式。
执行以下操作可能会更明确:
val verified: Option[Double] = Some(input).filter(isQualityOk)
这样类型系统会告诉您您不确定是否具有有效值(如果质量不佳,它将是 None
)。
如果您通常将函数 f(d: Double): T
应用于 verified
,只需执行 verified.map(f)
,以获得 Option[T]
,然后继续。
每当你需要一个真实的值时,你总是可以通过 verfied.getOrElse(BAD)
返回到 Double
,但最好将例外情况尽可能保持为 None
, 以便类型系统可以帮助您避免一些错误。