标题: C语言中的round函数
作者: Demon
链接: https://demon.tw/programming/c-round.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
C语言标准库中有没有round函数?答案是,可能有,也可能没有。这取决于你使用的编译器,更准确地说,是编辑器是否支持C99标准。
让我们简单回顾一下C语言标准的历史:C的第一个标准是由美国国家标准协会(ANSI)发布的。虽然这份文档后来被国际标准化组织(ISO)采纳并且ISO发布的修订版也被ANSI采纳了,但名称ANSI C(而不是 ISO C)仍被广泛使用。
C89
1983年,美国国家标准协会组成了一个委员会,X3J11,为了创立 C 的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,并在作为ANSI X3.159-1989 "Programming Language C"正式生效。这个版本的语言经常被称作"ANSI C",或有时称为"C89"(为了区别C99)。
C90
在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会采纳为ISO/IEC 9899:1990。这个版本有时候称为C90。因此,C89和C90通常指同一种语言。
C99
在ANSI的标准确立后,C语言的规范在一段时间内没有大的变动,然而C++在自己的标准化创建过程中继续发展壮大。《标准修正案一》在1995年为C语言创建了一个新标准,但是只修正了一些C89标准中的细节和增加更多更广得国际字符集支持。不过,这个标准引出了1999年ISO 9899:1999的发表。它通常被称为C99。C99被ANSI于2000年3月采用。
虽然C99标准已经确立了十多年,但是却没有流行起来。各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候,微软和Borland却似乎对此不感兴趣。而且很多人似乎连C99这个标准都没有听说过,现实中广泛使用的C语言标准仍然是C98,ANSI C也似乎成为了C98的代名词。
除了GCC完全兼容C99标准以外,目前大部分C编译器都不支持或者部分支持C99标准。即使是最新的Visual C++ 2010也仅支持一小部分C99,更不用说Windows 98那个年代发布的Visual C++ 6.0了(那时候C99标准都没有)。既然不支持C99,自然也就没有C99新增的标准库函数round。说了那么多废话,还是得自己写一个。我那么懒,当然不会自己去写,到PHP源码中抄了一份,在ext\standard\math.c文件中。
#include <stdio.h> #include <float.h> #include <math.h> #define zend_isinf(a) ((_fpclass(a) == _FPCLASS_PINF) || (_fpclass(a) == _FPCLASS_NINF)) #define zend_isnan(x) _isnan(x) static double php_round(double val, int places) { double t; double f = pow(10.0, (double) places); double x = val * f; if (zend_isinf(x) || zend_isnan(x)) { return val; } if (x >= 0.0) { t = ceil(x); if ((t - x) > 0.50000000001) { t -= 1.0; } } else { t = ceil(-x); if ((t + x) > 0.50000000001) { t -= 1.0; } t = -t; } x = t / f; return !zend_isnan(x) ? x : t; } int main(int argc, char *argv[]) { double d = php_round(5.055, 2); printf("%f\n", d); return 0; }
需要指出的是_fpclass和_isnan函数并不是C标准库函数,而是VC运行时库中的函数,即VC对C标准库的拓展,不具有可移植性。
赞赏微信赞赏支付宝赞赏
随机文章: