C中三位数精度的快速舍入浮点数

时间:2015-02-07 16:07:16

标签: c rounding

我看过这段代码:

(int)(num < 0 ? (num - 0.5) : (num + 0.5))

How to round floating point numbers to the nearest integer in C?) 对于舍入但我需要在点之后使用float和precision三位数。 例子: 254. 450 应该四舍五入到255。 254. 432 应向下舍入为254 254. 448 应向下舍入为254 等等。

注意:这就是我所说的“3位数字”后面的粗体数字。

我相信它应该比roundf()更快,因为当我需要计算轮数时,我会使用数十万轮。你有一些提示怎么做?我试图搜索roundf的来源,但没有找到。

注意:我需要它用于RGB2HSV转换功能,所以我认为3位数就足够了。我使用正数。

5 个答案:

答案 0 :(得分:3)

&#34;它应该比roundf()&#34;更快只能通过分析各种方法来验证。

要舍入到0个位置(舍入到最接近的整数),请使用roundf()

float f;
float f_rounded3 = roundf(f);

要使用float舍入到3个位置,请使用round()

  

round函数将它们的参数四舍五入为浮点格式的最接近的整数值,无论当前的舍入方向如何,都将中间情况四舍五入为零。

#include <math.h>

float f;
float f_rounded3 = round(f * 1000.0)/1000.0;

代码故意使用double的中间类型,否则使用缩小范围的代码:

float f_rounded3 = roundf(f * 1000.0f)/1000.0f;

如果代码在使用254.450或各种测试将255.0四舍五入到roundf()时遇到问题,可能是因为该值 254.450 ,但float靠近它254.4499969,它使用二进制格式转换为254.典型FP并且254.450不能完全表示。

答案 1 :(得分:0)

你可以使用双变换浮点数 - &gt; string - &gt;浮点数,而第一次转换后点数为3位数:

  sprintf(tmpStr, "%.3f", num);

答案 2 :(得分:0)

这项工作对我来说

#include <stdio.h>


int main(int ac, char**av)                                                                    
{                                                                                             
  float val = 254.449f;                                                                       
  float val2 = 254.450f;                                                                      
  int res = (int)(val < 0 ? (val - 0.55f) : (val + 0.55f));                                   
  int res2 = (int)(val2 < 0 ? (val2 - 0.55f) : (val2 + 0.55f));                               
  printf("%f %d %d\n", val, res, res2);                                                       
  return 0;                                                                                   
}                                                                                             

输出:254.449005 254 255

增加精度只需在0.55f中添加任意5个,如0.555f,0.5555f等

答案 3 :(得分:0)

我想要这样的东西:

float num = 254.454300;
float precision=10;
float p = 10*precision;
num = (int)(num  * p + 0.5) / p ;

但结果将是不准确的(有错误) - 我的x86机器给了我这个结果:254.449997

答案 4 :(得分:0)

对int进行类型转换并使用float(另外一个类型转换)操作很慢。使用零位舍入(整数)操作浮点数并返回浮点数进行n位舍入。

round_1(x)= round_0(10 * x)/ 10

round_2(x)= round_0(100 * x)/ 100

round_3(x)= round_0(1000 * x)/ 1000

round_n(x)= round_0(10 ^ n * x)/ 10 ^ n

对于更快的零位数圆形到浮动类型,您可以这样做:

inline float round( float x ){
    x += 12582912 ; // 3*2^22
    x -= 12582912 ;
    return x ;
}

如果不简化操作,如果| x | <= 2 ^ 23,它将舍入到最接近的整数。如果编译器使用FPU,它可以更快(没有浮点数,使用long double):

inline long double round( long double x ){
    x += ( sizeof(x)==8 ? 6755399441055744.0 : 27670116110564327424.0 ) ; // 3*2^51 or 3*2^63
    x -= ( sizeof(x)==8 ? 6755399441055744.0 : 27670116110564327424.0 ) ;
    return x ;
}

它适用于此(长双)。