'Most C system provide for logically infinite floating values' 是什么意思?
what is meant by 'Most C system provide for logically infinite floating values'?
最初我将变量 x 和 y 声明为 int 类型:
#include<stdio.h>
int main(){
int x, y = 0 ;
x = 1 / y;
printf("%d", x);
return 0;
}
程序崩溃(原因很明显)。
现在我将变量 x 和 y 声明为双精度:
#include<stdio.h>
int main(){
double x, y = 0 ;
x = 1 / y;
printf("%d", x);
return 0;
}
但输出:0。(为什么?)
然后我把printf中的%d改成了%f:
#include<stdio.h>
int main(){
double x, y = 0 ;
x = 1 / y;
printf("%f", x);
return 0;
}
输出:1.#INF00
我不明白这里发生了什么。
请解释一下以上情况。
您可能接触到的大多数系统都使用 IEEE 754 表示浮点数。该表示具有存储值 +infinity 和 -infinity 的方法。
虽然严格来说,除以 0 是 undefined behavior,但使用 IEEE 754 的实现扩展了语言以允许它用于浮点类型。在这种情况下,除以 0 可以被认为是无穷大,因此您的实现允许它,并且 1.#INF00
是 MSVC 打印无穷大值的方式。
此外,在您使用 %d
打印 double
的第二个示例中使用错误的格式说明符进行打印是未定义的行为。格式说明符必须与传入内容的数据类型相匹配。
计算机中没有数字。我们用物理部件构建计算机,并使用物理特性来存储和操作数据。
在不同的地方,计算机有电荷、电压、磁场或我们用来表示数据的其他物理事物。在这样做时,我们选择一些物理状态并将其称为“0”和其他一些状态并称为“1”。这些只是方便的名称。像 0 和 1 这样的数学数字是抽象的实体——它们是没有物理存在的概念。计算机中不存在数字 0 和 1。
我们将这些物理状态捆绑在一起,通常以 8 个、32 个或 64 个为一组,然后以各种方式标记它们。例如,对于标记为 00100010 的状态中的八位,我们可以称之为“34”。它仍然不是一个数字。我们只是对数字 34 使用二进制表示法,而该二进制表示法进一步指定了机器部件的状态。
状态 00100010 中的机器部件本质上不是实际数字 34,就像它们不是香蕉或红色的概念一样。
我们设计机器的部件,以便它们可以操纵这些状态。机器中的某处是一个 加法器 ,它将表示一个数字的物理状态和表示另一个数字的物理状态作为输入物理状态,并创建表示作为两个输入数字之和的数字的输出物理状态.
计算机包含许多这样的部件,它们可以产生加法、乘法、减法等效果。这些只是在机器中创建的效果。
对于浮点数,我们指定某些位模式来表示无穷大,并且我们设计浮点运算单元以相应地运行。当我们给浮点算术加法器一个代表无穷大的输入和另一个代表有限数的输入时,它会产生一个代表无穷大的输出,因为我们设计浮点算术单元就是为了做到这一点。类似地,当我们为浮点除法器提供一个代表数字 1 的输入和另一个代表数字 0 的输入时,它会产生代表无穷大的位模式作为输出,同样是因为我们将其设计为这样做。
当您使用 printf("%f", x);
打印一个浮点对象作为表示无穷大的位模式时,C 实现打印一个表示无穷大的字符串。微软为此选择的字符串是“1.#INF00”,这是相当难看的。其他一些实现使用“inf”,只是稍微好一点。
当您尝试使用 printf("%d", x);
打印浮点对象时,C 标准未定义此行为,因为 %d
转换需要接收 int
对象,但是您传递的 x
是一个 double
对象。传递错误类型的参数可能会以多种方式搞砸参数传递机制,因此在不了解软件内部工作原理的情况下,您不会总能得到有意义的答案。
最初我将变量 x 和 y 声明为 int 类型:
#include<stdio.h>
int main(){
int x, y = 0 ;
x = 1 / y;
printf("%d", x);
return 0;
}
程序崩溃(原因很明显)。
现在我将变量 x 和 y 声明为双精度:
#include<stdio.h>
int main(){
double x, y = 0 ;
x = 1 / y;
printf("%d", x);
return 0;
}
但输出:0。(为什么?)
然后我把printf中的%d改成了%f:
#include<stdio.h>
int main(){
double x, y = 0 ;
x = 1 / y;
printf("%f", x);
return 0;
}
输出:1.#INF00
我不明白这里发生了什么。
请解释一下以上情况。
您可能接触到的大多数系统都使用 IEEE 754 表示浮点数。该表示具有存储值 +infinity 和 -infinity 的方法。
虽然严格来说,除以 0 是 undefined behavior,但使用 IEEE 754 的实现扩展了语言以允许它用于浮点类型。在这种情况下,除以 0 可以被认为是无穷大,因此您的实现允许它,并且 1.#INF00
是 MSVC 打印无穷大值的方式。
此外,在您使用 %d
打印 double
的第二个示例中使用错误的格式说明符进行打印是未定义的行为。格式说明符必须与传入内容的数据类型相匹配。
计算机中没有数字。我们用物理部件构建计算机,并使用物理特性来存储和操作数据。
在不同的地方,计算机有电荷、电压、磁场或我们用来表示数据的其他物理事物。在这样做时,我们选择一些物理状态并将其称为“0”和其他一些状态并称为“1”。这些只是方便的名称。像 0 和 1 这样的数学数字是抽象的实体——它们是没有物理存在的概念。计算机中不存在数字 0 和 1。
我们将这些物理状态捆绑在一起,通常以 8 个、32 个或 64 个为一组,然后以各种方式标记它们。例如,对于标记为 00100010 的状态中的八位,我们可以称之为“34”。它仍然不是一个数字。我们只是对数字 34 使用二进制表示法,而该二进制表示法进一步指定了机器部件的状态。
状态 00100010 中的机器部件本质上不是实际数字 34,就像它们不是香蕉或红色的概念一样。
我们设计机器的部件,以便它们可以操纵这些状态。机器中的某处是一个 加法器 ,它将表示一个数字的物理状态和表示另一个数字的物理状态作为输入物理状态,并创建表示作为两个输入数字之和的数字的输出物理状态.
计算机包含许多这样的部件,它们可以产生加法、乘法、减法等效果。这些只是在机器中创建的效果。
对于浮点数,我们指定某些位模式来表示无穷大,并且我们设计浮点运算单元以相应地运行。当我们给浮点算术加法器一个代表无穷大的输入和另一个代表有限数的输入时,它会产生一个代表无穷大的输出,因为我们设计浮点算术单元就是为了做到这一点。类似地,当我们为浮点除法器提供一个代表数字 1 的输入和另一个代表数字 0 的输入时,它会产生代表无穷大的位模式作为输出,同样是因为我们将其设计为这样做。
当您使用 printf("%f", x);
打印一个浮点对象作为表示无穷大的位模式时,C 实现打印一个表示无穷大的字符串。微软为此选择的字符串是“1.#INF00”,这是相当难看的。其他一些实现使用“inf”,只是稍微好一点。
当您尝试使用 printf("%d", x);
打印浮点对象时,C 标准未定义此行为,因为 %d
转换需要接收 int
对象,但是您传递的 x
是一个 double
对象。传递错误类型的参数可能会以多种方式搞砸参数传递机制,因此在不了解软件内部工作原理的情况下,您不会总能得到有意义的答案。