程序开发中数值计算精度的精度控制标准化

程序开发中很多地方需要数值计算,有数值计算就有数值计算精度安全问题需要注关注。例如几何编辑、物理模拟、渲染着色计算等应用场景。常见的浮点数值计算精度问题会导致闪烁、裂缝等等瑕疵或错误。精度问题还会不停累计放大,如果计算规则不一致,加上开发者能力认知层次不齐,可能导致严重的错误。因此程序开发过程中应该提前将数值计算的精度控制统一起来,封装成符合项目需求的标准化操作。如下是TypeScript和c++两种语言的相关演示代码,用于交流探讨。

Typescript 演示代码:


/*******************************************************************************
* If the float number value is MATH_MAX_NEGATIVE < value < MATH_MIN_POSITIVE, 
* the value can be considered ZERO, otherwise the value is not ZERO.
*******************************************************************************/

/**
 * principle: x < MATH_MIN_POSITIVE, or x >= MATH_MIN_POSITIVE
 */
const MATH_MIN_POSITIVE = 1e-6;
/**
 * principle: x <= MATH_MAX_NEGATIVE, or x > MATH_MAX_NEGATIVE
 */
const MATH_MAX_NEGATIVE = -1e-6;

function isZero(v: number) : boolean {
	return v > MATH_MAX_NEGATIVE && v < MATH_MIN_POSITIVE;
}
function isNotZero(v: number) : boolean {
	return v <= MATH_MAX_NEGATIVE || v >= MATH_MIN_POSITIVE;
}
/**
 * example:
 *     isGreaterPositiveZero(0.1) is true
 *     isGreaterPositiveZero(0.000000001) is false
 *     isGreaterPositiveZero(-0.1) is false
 * @param v number value
 * @returns a positive number value and its value is greater zero, return true, otherwize false
 */
function isGreaterPositiveZero(v: number) : boolean {
	return v >= MATH_MIN_POSITIVE;
}
/**
 * example:
 *      isLessNegativeZero(-0.1) is true
 *      isLessNegativeZero(-000000001) is false
 *      isLessNegativeZero(0.1) is false
 * @param v number value
 * @returns a negative number value and its value is less zero, return true, otherwise false
 */
function isLessNegativeZero(v: number) : boolean {
	return v <= MATH_MAX_NEGATIVE;
}
/**
 * example:
 * 	isLessPositiveZero(+0.00000001) is true
 *  isLessPositiveZero(-1.3) is true
 *  isLessPositiveZero(1.3) is false
 * @param v number value
 * @returns true or false
 */
function isLessPositiveZero(v: number) : boolean {
	return v < MATH_MIN_POSITIVE;
}
/**
 * example:
 * 	isGreaterNegativeZero(-0.00000001) is true
 *  isGreaterNegativeZero(+1.3) is true
 *  isGreaterNegativeZero(-1.3) is false
 * @param v number value
 * @returns true or false
 */
function isGreaterNegativeZero(v: number) : boolean {
	return v > MATH_MAX_NEGATIVE;
}

function isPostiveZero(v: number) : boolean {
	return v >= 0.0 && v < MATH_MIN_POSITIVE;
}
function isNegativeZero(v: number) : boolean {
	return v <= 0.0 && v > MATH_MAX_NEGATIVE;
}
function isGreaterRealZero(v: number) : boolean {
	return v > 0.0;
}
function isLessRealZero(v: number) : boolean {
	return v < 0.0;
}

C++演示代码:

/*******************************************************************************
* If the float number value is MATH_MAX_NEGATIVE < value < MATH_MIN_POSITIVE, 
* the value can be considered ZERO, otherwise the value is not ZERO.
*******************************************************************************/

/**
 * principle: x < MATH_MIN_POSITIVE, or x >= MATH_MIN_POSITIVE
 */
const double MATH_MIN_POSITIVE = 1e-6;
/**
 * principle: x <= MATH_MAX_NEGATIVE, or x > MATH_MAX_NEGATIVE
 */
const double MATH_MAX_NEGATIVE = -1e-6;

inline bool isZero(double v) {
	return v > MATH_MAX_NEGATIVE && v < MATH_MIN_POSITIVE;
}
inline bool isNotZero(double v) {
	return v <= MATH_MAX_NEGATIVE || v >= MATH_MIN_POSITIVE;
}
/**
 * example:
 *     isGreaterPositiveZero(0.1) is true
 *     isGreaterPositiveZero(0.000000001) is false
 *     isGreaterPositiveZero(-0.1) is false
 * @param v number value
 * @returns a positive number value and its value is greater zero, return true, otherwize false
 */
inline bool isGreaterPositiveZero(double v) {
	return v >= MATH_MIN_POSITIVE;
}
/**
 * example:
 *     isLessNegativeZero(-0.1) is true
 *     isLessNegativeZero(-0.000000001) is false
 *     isLessNegativeZero(0.1) is false
 * @param v number value
 * @returns a negative number value and its value is less zero, return true, otherwise false
 */
inline bool isLessNegativeZero(double v) {
	return v <= MATH_MAX_NEGATIVE;
}
/**
 * example:
 * 	isLessPositiveZero(+0.00000001) is true
 *  isLessPositiveZero(-1.3) is true
 *  isLessPositiveZero(1.3) is false
 * @param v number value
 * @returns true or false
 */
inline bool isLessPositiveZero(double v) {
	return v < MATH_MIN_POSITIVE;
}
/**
 * example:
 * 	isGreaterNegativeZero(-0.00000001) is true
 *  isGreaterNegativeZero(+1.3) is true
 *  isGreaterNegativeZero(-1.3) is false
 * @param v number value
 * @returns true or false
 */
inline bool isGreaterNegativeZero(double v) {
	return v > MATH_MAX_NEGATIVE;
}

inline bool isPostiveZero(double v) {
	return v >= 0.0 && v < MATH_MIN_POSITIVE;
}
inline bool isNegativeZero(double v) {
	return v <= 0.0 && v > MATH_MAX_NEGATIVE;
}
inline bool isGreaterRealZero(double v) {
	return v > 0.0;
}
inline bool isLessRealZero(double v) {
	return v < 0.0;
}

以上示例代码用于对浮点函数的相关判断做了统一的封装,以便保证统一的计算效果。而不会因为一时的编码习惯而导致计算机制不一致。例如:

>MATH_MIN_POSITIVE 和 >= MATH_MIN_POSITIVE 就是不一样的。这种不同会导致结果差异而埋下难以提前察觉的错误。

当然,全面的数值精度管理,还要考虑软件功能设计目标需求的差异、运行环境的差异(或跨语言的实现)等等因素。总的来讲,能预先规避问题,总是更有价值的选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值