提问人:Kelson Ball 提问时间:5/19/2018 最后编辑:ShepmasterKelson Ball 更新时间:5/19/2018 访问量:384
使用 f64::mul_add 时如何引入额外的舍入误差?
How is additional rounding error introduced when using f64::mul_add?
问:
根据文档,f64::mul_add
可用于减少舍入错误的机会:
pub fn mul_add(self, a: f64, b: f64) -> f64
融合乘加。仅使用一次舍入进行计算 错误。这将产生更准确的结果和更好的性能 而不是单独的乘法运算,后跟加法。
(self * a) + b
我正在开发一个非常常见的线性变换库。当我引入结构的点积时,我失去了精度。a * b + ...
mul_add
AffineVector
这是点积法:
impl AffineVector {
pub fn dot(self, v: AffineVector) -> f64 {
self.x * v.x + self.y * v.y + self.z * v.z + self.w * v.w
// self.x.mul_add(v.x, self.y.mul_add(v.y, self.z.mul_add(v.z, self.w * v.w)))
}
}
在实现且没有其他更改的情况下,以下测试会失败,因为最后一个断言的浮点精度问题:mul_add
#[test]
fn inverse_rotation() {
// create a rotation matrix for 1 radian about the Z axis
let rotate = AffineMatrix::new(Primitives::RotationZ(1.));
// create a matrix that undoes the rotation of 'rotate'
let revert = rotate.inverse();
// apply the transformation to the vector <1,0,0>
let rotated = rotate.apply_vec3(KVector3::i_hat());
// assert that the result is <cos(1),sin(1),0>
let expected = KVector3::new(C, S, 0.0);
assert_eq!(rotated, expected);
// use the 'revert' matrix to undo the rotation
let returned = revert.apply_vec3(rotated);
// assert that the result is back to <1,0,0>
assert_eq!(returned, KVector3::i_hat());
}
panicked at 'assertion failed: `(left == right)`
left: `KVector3 { x: 1.0, y: 0.000000000000000023419586346110148, z: 0.0 }`,
right: `KVector3 { x: 1.0, y: 0.0, z: 0.0 }`',
使用如何以及为什么会降低精度?我怎样才能有效地使用它?mul_add
答: 暂无答案
评论
0.1 + 0.2
0.3
0.1 + 0.2 == 0.3