FLT_EPSILON-----浮点数的比较

本文介绍了FLT_EPSILON、__FLT_EPSILON__、DBL_EPSILON、__DBL_EPSILON__和LDBL_EPSILON、__LDBL_EPSILON__在编程中的作用,尤其是在比较浮点数值的精确度时。通过实例演示了正确使用这些常量避免比较误差的方法。

FLT_EPSILON__FLT_EPSILON__是一个意思,表示的是float类型(单精度浮点数)所能识别的最小精度。DBL_EPSILON__DBL_EPSILON__表示的是double类型所能识别的最小精度,LDBL_EPSILON__LDBL_EPSILON__表示的是long double类型所能识别的最小精度;它们常用于比较当中:

一、使用场景

double a = 0.5;
if (a == 0.5) {
    NSLog(@"a = 0.5是正确的。");
} else {
    NSLog(@"a = 0.5不是正确的。");
}
NSLog(@"a的值为: %f", a);

double b = sin(M_PI / 6.0);
if (b == 0.5) {
    NSLog(@"b = 0.5是正确的。");
} else {
    NSLog(@"b = 0.5不是正确的。");
}
NSLog(@"b的值为:%f", b);

第一个比较正确,因为0.5double类型的存储精度范围内;
第二个比较可能正确也可能错误,结果取决于处理器、编译器的版本和设置;

二、正确用法

上面比较b的正确方法应该是这样:

double b = sin(M_PI / 6.0);
if (fabs(b - 0.5) < DBL_EPSILON) {
    NSLog(@"b = 0.5是正确的。");
} else {
    NSLog(@"b = 0.5不是正确的。");
}
NSLog(@"b的值为:%f", b);

转自https://www.jianshu.com/p/6f57ec7ee660

void gmm_process(VFRAME *vframe, GMM_CONTEXT *gmm_context, U8 *dst, float learningrate) { U32 alpha = learningrate * GMM_SCALE, vt = gmm_context->config.var_thresh; float background_ratio = gmm_context->config.background_ratio; U32 mixtures = gmm_context->config.max_mixtures; GMM_MixData *gmm_model = gmm_context->gmm_model; GMM_MixData gmm_tmp_model; U32 frame_width = gmm_context->width; U32 frame_height = gmm_context->height; S32 row, col, k, m; float *sqrt_lut = get_sqrt_mapping_table(); const S32 w0 = gmm_context->config.weight_init; const float sk0 = (1.0 * w0 / (gmm_context->config.noise_sigma * 2)); const S32 var0 = gmm_context->config.noise_sigma * gmm_context->config.noise_sigma * 4; const S32 minvar = gmm_context->config.noise_sigma * gmm_context->config.noise_sigma; gmm_context->fg_corse_cnt = 0; for (row = 0; row < frame_height; row++) { VFRAME *frame_ptr = vframe + row * frame_width; FG *fg_data = dst + row * frame_width; if (alpha > 0) { for (col = 0; col < frame_width; col++, gmm_model += mixtures) { float wsum = 0.0; S32 pixel = frame_ptr[col]; S32 khit = -1, kfg = -1; for (k = 0; k < mixtures; k++) { U8 weight = gmm_model[k].weight; if (weight < FLT_EPSILON) { break; } S32 mu = gmm_model[k].mean; U16 var = gmm_model[k].var; S32 diff = pixel - mu; U32 diff_square = diff * diff; if (diff_square < vt * var) { S32 dweight = alpha * (GMM_SCALE - weight) / GMM_SCALE; gmm_model[k].weight = weight + dweight; if (diff > 36 || diff < -36) { gmm_model[k].mean = mu + (alpha * diff) / GMM_SCALE; } else if (diff != 0) { gmm_model[k].mean = mu + (diff > 0 ? 1 : -1); } S32 dvar = diff_square - var; S32 tempvar = var; if (dvar > 36 || dvar < -36) { tempvar += alpha * dvar / GMM_SCALE; } else if (dvar != 0) { tempvar += (dvar > 0 ? 1 : -1); } var = UTILS_MAX(tempvar, minvar); gmm_model[k].var = var; gmm_model[k].sortkey = weight / sqrt_lut[var]; for (m = k - 1; m >= 0; m--) { if (gmm_model[m].sortkey >= gmm_model[m + 1].sortkey) { break; } UTILS_SWAP_BY_TMP(gmm_model[m], gmm_model[m + 1], gmm_tmp_model); } khit = m + 1; break; } else { S32 dweight = alpha * weight / GMM_SCALE; gmm_model[k].weight = weight - dweight; wsum += gmm_model[k].weight; } } if (khit < 0) { khit = k = UTILS_MIN(k, mixtures - 1); wsum += w0 - gmm_model[k].weight; gmm_model[k].weight = w0; gmm_model[k].mean = pixel; gmm_model[k].var = var0; gmm_model[k].sortkey = sk0; } else { for (; k < mixtures; k++) { wsum += gmm_model[k].weight; } } float weight_scale = 1.f / wsum; wsum = 0; for (k = 0; k < mixtures; k++) { wsum += gmm_model[k].weight * weight_scale; if (wsum > background_ratio) { kfg = k + 1; break; } } if (khit >= kfg) { fg_data[col] = 1; gmm_context->fg_corse_cnt++; } else { fg_data[col] = 0; } } } } } 将这段代码升级为gmm v2
09-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值