Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.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 - Fatal编程技术网

C 当浮点数不能表示整数时,它会做什么

C 当浮点数不能表示整数时,它会做什么,c,floating-point,C,Floating Point,我们知道,对于具有n位分数的浮点格式,给出了无法精确表示的最小正整数的公式(因为它需要n+1位分数才能精确表示)。因此,对于单精度格式,其中分形位n=23: 它不能精确表示的最小正整数是2^24+1。所以我的问题是,假设我们碰巧用这个数字作为 float a = ...; float b = ...; float c= a+b; //where a+b is 2^24+1 那么C在这里做什么呢?让它溢出?我们怎么会因为总是有机会遇到无法表示的整数而使用浮点数而感到困惑呢?这会降低精度,可能

我们知道,对于具有n位分数的浮点格式,给出了无法精确表示的最小正整数的公式(因为它需要n+1位分数才能精确表示)。因此,对于单精度格式,其中分形位n=23:

它不能精确表示的最小正整数是
2^24+1
。所以我的问题是,假设我们碰巧用这个数字作为

float a = ...;
float b = ...;
float c= a+b;  //where a+b is 2^24+1
那么C在这里做什么呢?让它溢出?我们怎么会因为总是有机会遇到无法表示的整数而使用浮点数而感到困惑呢?这会降低精度,可能会在银行系统中造成严重后果

那么C在这里做什么呢

C标准让实现来指定发生了什么。C 2018第5.2.4.2.2 7条规定:

浮点运算(
+
-
*
/
)以及
中返回浮点结果的库函数的精度由实现定义,由
中的库函数执行的浮点内部表示和字符串表示之间的转换精度也是如此。实现可能会声明精度未知

通常,对于
+
-
*
/
的操作,C实现生成最接近实数结果的可表示结果,并将关系四舍五入到具有偶数低位的可表示数,需要注意的是,对于中间结果,某些C实现可能使用比标称类型更高的精度(例如,即使表达式只包含
double
数字,也使用
long double
计算所有表达式,然后将最终结果转换为
double
以进行赋值)

对于“简单”的数学例程,例如
fma
,通常会返回上面四舍五入的结果。对于复杂函数,如三角函数和对数函数,C实现的精度各不相同

对于浮点和十进制文本之间的转换,例如使用
scanf
printf
strod
,实现的质量各不相同。好的实现将产生正确的四舍五入结果

让它溢出

浮点中的“溢出”是指超出浮点格式有限范围的结果,即,即使考虑舍入,结果的大小也超过格式中可表示的最大有限值。它不引用超出所有整数都可表示的格式范围的结果

我们如何能够[有信心]使用浮点数,因为总是有机会遇到无法表示的[整数]数字,这会降低精度,并可能在银行系统中造成严重的[后果]

由于C标准未提供所需的保证,因此必须使用C实现的文档,以使用或避免C中的浮点运算。许多C实现在一定程度上使用IEEE-754标准进行浮点运算,并且它提供了有关舍入行为的要求。软件工程师必须选择精度足够的浮点格式,以满足其使用目的


请注意,这个问题并非浮点运算所独有。整数算术同样不能表示金融算术和其他情况下出现的数字。例如,计算利息很快就会产生分数,因此程序员必须设计他们的软件来正确计算,即使分数无法表示。当然,整数运算可能会溢出。无论使用何种数字格式,软件工程师都必须注意其属性和限制。

除了使用整数表示货币外,请阅读其他内容,不要期望浮点值是准确的。在一个有限的存储空间中,可以表示的离散值(从无限范围)非常之多。2^24-1肯定可以表示为
float
。最小的不可表示正整数为2^24+1。如果希望能够表示任何
int
,请使用
double
而不是
float
。事实上,除非你有很好的理由,否则一定要使用
double
@rici抱歉,那是个打字错误,我的意思是2^24+1。因此,即使我使用了
double
,我仍然有可能处理2^53+1,它仍然不能用
double
精确表示?@amjad:可能的可表示数只有有限个,其中一些不是整数。所以有些整数不能精确表示。但是2^53比任何
int
(在大多数平台上)都大,因此可以说每个
int
都有一个精确的
表示。这有时是有用的(但标准没有保证)。