Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将浮点结果向下舍入_C_Floating Point_Double_Rounding - Fatal编程技术网

C 将浮点结果向下舍入

C 将浮点结果向下舍入,c,floating-point,double,rounding,C,Floating Point,Double,Rounding,我有两个浮点(双精度)值a和b,我想把它们相加得到一个结果c 我知道c会以某种方式近似,因为一切都是有限精度的。现在,我想“向下舍入”c,这意味着浮点c不大于浮点a和b的实际总和,或者c根据您的描述,似乎您想要控制浮点运算的舍入模式。在C99中,头文件fenv.h中提供的功能支持这一点。您可能需要指示编译器启用C99支持,并且可能需要指示它以符合IEEE-754的方式执行浮点运算。下面是一个最小的示例,演示了如何使用截断(向零舍入)执行double加法。由于已知操作数为正,这相当于向下舍入(接近

我有两个浮点(双精度)值a和b,我想把它们相加得到一个结果c


我知道c会以某种方式近似,因为一切都是有限精度的。现在,我想“向下舍入”c,这意味着浮点c不大于浮点a和b的实际总和,或者c根据您的描述,似乎您想要控制浮点运算的舍入模式。在C99中,头文件
fenv.h
中提供的功能支持这一点。您可能需要指示编译器启用C99支持,并且可能需要指示它以符合IEEE-754的方式执行浮点运算。下面是一个最小的示例,演示了如何使用截断(向零舍入)执行
double
加法。由于已知操作数为正,这相当于向下舍入(接近负无穷大)

一个棘手的问题

上面对“向0取整”的评论很好,将提供最佳结果

#ifdef _ _STDC_IEC_559_ _ 
    fesetround(FE_DOWNWARD);
    c = a + b;
#else
   #error unable to set rounding mode
#endif
OP最初的方法也很接近。任何好的编译/处理器都应该能够在0.5或1.0 ULP(取决于舍入模式)中创建对的最佳答案。它肯定会创建一个小于算术
a+b
的和
c2
,但是
c
也可能满足要求

c = a + b
c2 = nextafter(c, -DBL_MAX);

c=楼层(a+b)
将不起作用,因为
a
的大小可能远远大于一些较小的负值
b
,因此计算出的和仍然是简单的
a
,并且无法通过算术
c如果c是整数类型,那么您至少可以在某些体系结构上设置舍入模式为向零或向零舍入负无穷大:
ieee754 1985:4.2。定向环行一种实施方式还应提供三种用户可选择的定向环行模式:向+无限方向环行、向-无限方向环行和向0方向环行。
与风向标相同,但路线较长,
c=地板(-1*(a+b))*-1
;如果十进制舍入有问题。@user3528438它是浮点类型,而不是整数。如果它是整数,那么就没有问题了。@WeatherVane我编辑了这篇文章,我感兴趣的是找到一个浮点值,而不是一个整数。抱歉说得含糊不清。
                  a = 0x1.fffffffffffffp+1023
                a+a = 0x1.#INF000000000p+0
round_to_zero (a+a) = 0x1.fffffffffffffp+1023
#ifdef _ _STDC_IEC_559_ _ 
    fesetround(FE_DOWNWARD);
    c = a + b;
#else
   #error unable to set rounding mode
#endif
c = a + b
c2 = nextafter(c, -DBL_MAX);