有没有办法在C中舍入数字?
我不想使用ceil和地板.还有其他选择吗?
当我用Google搜索答案时,我遇到了这段代码:
(int)(num < 0 ? (num - 0.5) : (num + 0.5))
Run Code Online (Sandbox Code Playgroud)
即使float num = 4.9,上面的行总是将值打印为4.
chu*_*ica 13
在C中对a进行舍入float,有3个<math.h>函数可以满足需要。推荐rintf()。
float nearbyintf(float x);\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n这些
\nnearbyint函数使用当前舍入方向将其参数舍入为浮点格式的整数值,并且不提高 \xe2\x80\x98\xe2\x80\x98inexact\xe2\x80\x99\xe2\x80\x99 浮点数例外。C11dr \xc2\xa77.12.9.3 2
或者
\n\nfloat rintf(float x);\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n这些
\nrint函数与nearbyint函数 (7.12.9.3) 的不同之处仅在于,rint如果结果为,则函数可能会引发 \xe2\x80\x98\xe2\x80\x98inexact\xe2\x80\x99\xe2\x80\x99 浮点异常与参数的值不同。C11dr \xc2\xa77.12.9.4 2
或者
\n\nfloat roundf(float x);\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n这
\nround函数将其参数舍入为最接近的浮点格式整数值,将中间情况舍入到远离零的位置,无论当前舍入方向如何。C11dr \xc2\xa77.12.9.6 2
例子
\n\n#include <fenv.h>\n#include <math.h>\n#include <stdio.h>\n\nvoid rtest(const char *fname, double (*f)(double x), double x) {\n printf("Clear inexact flag :%s\\n", feclearexcept(FE_INEXACT) ? "Fail" : "Success");\n printf("Set round to nearest mode:%s\\n", fesetround(FE_TONEAREST) ? "Fail" : "Success");\n\n double y = (*f)(x);\n printf("%s(%f) --> %f\\n", fname,x,y);\n\n printf("Inexact flag :%s\\n", fetestexcept(FE_INEXACT) ? "Inexact" : "Exact");\n puts("");\n}\n\nint main(void) {\n double x = 8.5;\n rtest("nearbyint", nearbyint, x);\n rtest("rint", rint, x);\n rtest("round", round, x);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n输出
\n\nClear inexact flag :Success\nSet round to nearest mode:Success\nnearbyint(8.500000) --> 8.000000\nInexact flag :Exact\n\nClear inexact flag :Success\nSet round to nearest mode:Success\nrint(8.500000) --> 8.000000\nInexact flag :Inexact\n\nClear inexact flag :Success\nSet round to nearest mode:Success\nround(8.500000) --> 9.000000\nInexact flag :Exact\nRun Code Online (Sandbox Code Playgroud)\n\nOP 的代码有什么弱点?
\n\n(int)(num < 0 ? (num - 0.5) : (num + 0.5))\nRun Code Online (Sandbox Code Playgroud)\n\n如果num值不接近该int范围,则转换(int)会导致未定义的行为。
当num +/- 0.5导致答案不准确时。这在这里不太可能,因为0.5adouble会导致加法以比 更高的精度发生float。当num和0.5具有相同的精度时,0.5与数字相加可能会得到数字四舍五入的结果。(这不是 OP 帖子的整数四舍五入。)示例:根据 OP 的目标,略小于 0.5 的数字应四舍五入为 0,但会得到 1.0 和略小于 1.0 的num + 0.5最小值之间的精确答案double。由于确切的答案无法表示,因此总和通常会四舍五入到 1.0,从而导致错误的答案。类似的情况也会发生在大量的情况下。
OP 的困境是“即使在 时,上面的行也始终将值打印为 4 float num =4.9”。是无法解释的。需要额外的代码/信息。我怀疑OP可能用过int num = 4.9;.
// avoid all library calls\n// Relies on UINTMAX_MAX >= FLT_MAX_CONTINUOUS_INTEGER - 1\nfloat my_roundf(float x) {\n // Test for large values of x \n // All of the x values are whole numbers and need no rounding\n #define FLT_MAX_CONTINUOUS_INTEGER (FLT_RADIX/FLT_EPSILON)\n if (x >= FLT_MAX_CONTINUOUS_INTEGER) return x;\n if (x <= -FLT_MAX_CONTINUOUS_INTEGER) return x;\n\n // Positive numbers\n // Important: _no_ precision lost in the subtraction\n // This is the key improvement over OP\'s method\n if (x > 0) {\n float floor_x = (float)(uintmax_t) x;\n if (x - floor_x >= 0.5) floor_x += 1.0f;\n return floor_x;\n }\n\n if (x < 0) return -my_roundf(-x);\n return x; // x is 0.0, -0.0 or NaN\n}\nRun Code Online (Sandbox Code Playgroud)\n\n测试很少——稍后当我有时间的时候会这样做。
\n4.9 + 0.5是5.4,除非编译器严重损坏,否则不能四舍五入到4.
我刚刚确认Google搜索代码给出了4.9的正确答案.
marcelo@macbookpro-1:~$ cat round.c
#include <stdio.h>
int main() {
float num = 4.9;
int n = (int)(num < 0 ? (num - 0.5) : (num + 0.5));
printf("%d\n", n);
}
marcelo@macbookpro-1:~$ make round && ./round
cc round.c -o round
5
marcelo@macbookpro-1:~$
Run Code Online (Sandbox Code Playgroud)
我不确定这是个好主意。该代码取决于强制转换,我很确定确切的截断是未定义的。
float result = (num - floor(num) > 0.5) ? ceil(num) : floor(num);
Run Code Online (Sandbox Code Playgroud)
我会说这是一个更好的方法(这基本上是 Shiroko 发布的),因为它不依赖于任何演员表。