如何检查int是否在+/-某个百分比范围内

时间:2015-10-12 16:32:35

标签: c

我正在写这个函数,它接收2个数字ref和数据,并检查数据是否在ref的5%之内。

示例:如果ref为100且数据为102,则返回1.

<button class="nm-simple-add-to-cart-button single_add_to_cart_button button alt" data-dismiss="modal" aria-label="Close" onclick="document.getElementById('coupon_code').value = 'THECOUPONCODE';" alutocomplete="off" id="gencode">Generate a Code</button>

我遇到的问题是在lower_bound。当我将100作为ref传递时,upper_bound是105但是由于某种原因,lower_bound是94,当它应该是95时。

5 个答案:

答案 0 :(得分:2)

要将此转换为整数算术,我们ref - 0.05 * ref = 0.95 * ref = 19/20 * ref,类似ref + 0.05 * ref = 21/20 * {{1} }。

因此,我们要检查19/20 * refref≤21/ 20 * data,换句话说是ref。然后代码变为

19 * ref <= 20 * data && 20 * data <= 21 * ref

请注意,浮点运算的任何问题都消失了。但是,如果int within_5_percent(int ref, int data) { int result = 0; // printf("Upper: %d\n",upper_bound); // printf("Lower: %d\n", lower_bound); if(20 * data >= 19 * ref && 20 * data <= 21 * ref) { result = 1; } else { result = 0; } return result; } ref太大(即为正)或太小(即为负),则可能会出现整数溢出问题。

答案 1 :(得分:1)

lower_bound的值为94,因为0.05不能完全代表double,转换回int会截断分数。

int lower_bound = (int) 100 - (double) 0.05 * (int) 100 -->   
int lower_bound = 100 - 0.05000000000000000277... * 100 -->  
int lower_bound = 94.999....999... -->  
int lower_bound = 94;

仅使用整数数学的简单替代方案。

int within5(int ref, int data) {
  int lo = ref - ref/20;
  int hi = ref + ref/20;
  return (lo <= data && data <= hi);
}

由于以上和其他各种答案均以ref为负或值较大而失败,因此以下是一种更安全的方法,我认为该方法适用于所有ref,data

int within5secure(int ref, int data) {
  int ref20 = abs(ref / 20);
  int lo = ref > INT_MIN + ref20 ? ref - ref20 : INT_MIN;
  int hi = ref < INT_MAX - ref20 ? ref + ref20 : INT_MAX;
  return (lo <= data && data <= hi);
}

答案 2 :(得分:0)

0.05 * ref触发C的类型提升规则并评估为double。 ref - 0.05 * ref然后做同样的事情,所以(ref - 0.05 * ref)的输出是双倍的。 int lower_bound的效果=(ref - 0.05 * ref);然后将一个double分配给一个int,它由截断执行。对于正浮点数,这意味着四舍五入。 因此,你所遭受的只是四舍五入的错误。您可以使用round(ref - 0.05 * ref)来获得最接近的整数而不是它下面的整数,或者您可以用整数执行整个计算,例如lower_bound =(ref * 95)/ 100;

答案 3 :(得分:0)

0.05 * ref

将结果转换为double。它不能直接表示为浮点数,因此实际结果类似于5.000000001

100 - 5.000001 = 94.99999999

然后将其截断为94。

这取决于你想要解决的问题,但你可以乘以5然后除以100得到5%。但是在这里你仍然需要定义如何在除法后对结果进行舍入。

答案 4 :(得分:0)

只需在代码中将int lower_boundint upper_bound更改为float lower_boundfloat upper_bound,因为在计算lower_bound = (ref - 0.05 * ref) and upper_bound = (ref + 0.05 *ref)时,最终可能会得到小数答案。例如,当ref=90 upper_bound94.5lower_bound85.5时,<{1}}。

int within_5_percent(int ref, int data)
{
   int result = 0;
   float lower_bound = (ref - 0.05 * ref);
   float upper_bound = (ref + 0.05 * ref);

   // printf("Upper: %f\n",upper_bound);
   // printf("Lower: %f\n", lower_bound);
 if(data >= lower_bound && data <= upper_bound)
 {
    result = 1;
 }
 else
 {
  result = 0;
 }

 return result;
}