小赖子的英国生活和资讯

代码审核之限制参数范围

阅读 桌面完整版

这两天又看到一个历史遗留下来写得很糟糕的代码. 这个代码大概是求两条线的夹角.

how-to-test-bad-smell-code 代码审核之限制参数范围 代码审核 程序设计

这两天又看到一个历史遗留下来写得很糟糕的代码. 这个代码大概是求两条线的夹角.

发现这代码是因为有一个单元测试不通过, DEBUG进来 发现是因为 Acos 函数在输入参数大于 1的时候返回 Nan, 浮点运算有误差返回了类似 1.00000012 之类的大于1但是却很靠近1的数值.

比如JS里:

js-math-acos

最后面的解决方法是:

1
Math.acos(Math.max(Math.min(1, x), -1));
Math.acos(Math.max(Math.min(1, x), -1));

通过这种方法把参数强制规定在-1到1期间. 但是这样的代码并不优美. 如果精度要求更严格, 可以自定义一个数值类型的类, 分开用整数来保存整数部分和小数部分, 这样需要定义加减乘除的运算, 但是由于整数部分参加运算没有精度损失, 所以不会有这样的问题. 不过得小心处理像进位这样的问题.

通过这种方法把参数强制规定在-1到1期间. 但是这样的代码并不优美. 如果精度要求更严格, 可以自定义一个数值类型的类, 分开用整数来保存整数部分和小数部分, 这样需要定义加减乘除的运算, 但是由于整数部分参加运算没有精度损失, 所以不会有这样的问题. 不过得小心处理像进位这样的问题.

撇开重新造轮子的问题(.NET 有像 Math.Net的库了), 所以完全可以用现成的库来操作这些向量. 即使你不用, 你也需要考虑重载这些三维向量的加减乘除运算, 上面的代码很容易下标给弄错了. 不好维护.

英文: Code Review – Bound Parameter

强烈推荐

微信公众号: 小赖子的英国生活和资讯 JustYYUK

阅读 桌面完整版
Exit mobile version