快捷搜索:  汽车  科技

c语言pow函数用法(为什么一定要慎用C语言标准库中的pow函数)

c语言pow函数用法(为什么一定要慎用C语言标准库中的pow函数)另外这还和编译器有很大的关系,有的编译器能保证计算结果正确,而像我使用的IAR自带的编译器就不行了。类似的标准库中很多函数如三角函数也会存在这个问题,所以大家在使用pow函数时要十分慎重,尤其是将结果往整数转换时。找到问题的原因所在就好解决了,针对这个特点我们可以采取四舍五入的办法,比如可以在结果的基础上加一个很小的常量值 const double eps = 1e-6; 还可以用round函数直接进行四舍五入。 可以看到计算结果符合预期,但是最近在用MSP430做远程升级时遇到了这样一个问题:升级前平台会发送一帧升级包的描述信息,其中包含总帧数,用可显字符来表示,例如要传输的总帧数是167帧,那么表示就是''167'',我需要将其转换成167并存储,根据其规律我先想到了用pow函数来解决,也就是a * 100 b * 10 c的思路,但是计算出来的

pow函数是C语言标准库中自带的一个计算函数,其接口存在于math.h文件中,所以使用前要先包含math.h文件。该函数用途是计算x的y次方,并将结果返回给用户,直接调用非常方便。在TC2.0中其原型为extern float pow(float x float y); ,而在VC6.0中原型为double pow( double x double y )。

VC6.0中的代码实现:


c语言pow函数用法(为什么一定要慎用C语言标准库中的pow函数)(1)

pow函数使用范例

可以看到计算结果符合预期,但是最近在用MSP430做远程升级时遇到了这样一个问题:

升级前平台会发送一帧升级包的描述信息,其中包含总帧数,用可显字符来表示,例如要传输的总帧数是167帧,那么表示就是''167'',我需要将其转换成167并存储,根据其规律我先想到了用pow函数来解决,也就是a * 100 b * 10 c的思路,但是计算出来的结果总为166,从而导致升级一直不成功,真是百思不得其解。

c语言pow函数用法(为什么一定要慎用C语言标准库中的pow函数)(2)

后来仔细研究了一下pow函数的实现,终于发现问题所在,pow函数由于参数和返回值都是double类型,其在计算机内存中表示方式本身就是一种近似,存在一定表达误差,比如100.0在内存中可能用99.999999来表示,而其转换为unsigned int类型时会导致精度丢失,造成转换结果为99。

找到问题的原因所在就好解决了,针对这个特点我们可以采取四舍五入的办法,比如可以在结果的基础上加一个很小的常量值 const double eps = 1e-6; 还可以用round函数直接进行四舍五入。

c语言pow函数用法(为什么一定要慎用C语言标准库中的pow函数)(3)

另外这还和编译器有很大的关系,有的编译器能保证计算结果正确,而像我使用的IAR自带的编译器就不行了。类似的标准库中很多函数如三角函数也会存在这个问题,所以大家在使用pow函数时要十分慎重,尤其是将结果往整数转换时。

猜您喜欢: