【发布时间】:2020-12-29 17:18:00
【问题描述】:
目前我是 C 的新手,我正在为一门课程做作业。任务是编写两个程序来计算tan(x),x 从 0 递增到 pi/2。一个程序必须使用浮点数,而另一个程序需要使用双精度数。作业的目标是了解输出的差异,因为它是科学编程课程的一部分。
到目前为止,我编写了这个程序:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
double x;
double pi;
pi = M_PI;
for (x = 0; x <= pi / 2; x += pi / 20)
{
printf("x = %f, tan = %f\n", x, tan(x));
}
exit(0);
}
我得到反馈说输出是双倍的。昨天我开始了一个与这段代码相关的线程,但是由于出现了不同的问题,所以开始一个新的似乎是合适的。
循环的一般原理有效,但我不知道下一步该做什么。
让我们首先处理程序的双版本。由于我需要计算 tan(x) 和 x 不是 100% 精确,由于小数增量,我认为将变量定义为双精度是很重要的。昨天得知printf函数的输出是双倍的。因此,我假设代码对于以 double 计算的目标是正确的。
在这里,我有一个小问题。我还打印了.20f,它给了我那个特定的窗口。我学到了一些关于 32 位和 64 位的知识。 Double 是 64 位的,可以在内存中存储 15 位小数。
问题:以上代码是否达到了双精度目标?
问题:如果内存已经超出,其他小数(第 16 位到第 20 位)从何而来?
对于float版本的程序,我需要将变量定义为float。
double x;
double pi;
变成
float x;
float pi;
然后是 printf 语句,在这里它变得有点混乱,因为我现在知道 printf 函数以双精度输出。但是我想要单精度并且仍然可以打印出来。我找不到另一个专门以单精度打印的函数。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float x;
float pi;
pi = M_PI;
for (x = 0; x <= pi / 2; x += pi / 20)
{
printf("x = %f, tan = %f\n", x, tan(x));
}
exit(0);
}
问题:如何以单精度打印?
问题:我需要在最后一个程序中进行哪些更改才能达到浮动程序的目标?
我渴望学习,但这有点难,因为由于 Covid-19,我们不再被允许进入大学。我希望有人能给我反馈。
谢谢, 叔
【问题讨论】:
-
第 1 步是查看 IEEE 754 floating point format 并了解幕后情况。请记住,虽然它只能存储特定数量的二进制数字,这转换为十进制数字的粗略数量,但从二进制转换为十进制可能会在最后引入额外的数字作为转换过程的工件。例如,1/8th 是 0.125,即三位数字,尽管二进制中的 8 只有三位。
-
您无法让
printf以单精度打印,所有float参数将自动提升为double.这是作为default argument promotion 的一部分完成的,所有variadic function 参数都会发生这种情况。 -
printf本来就很好。但是您应该使用tanf函数。tanf接受float参数,并返回float结果。 -
printf的输出不是double。printf的输出是一个字符序列,例如“1.347”。你说printf的输出是double是什么意思?你说的是它打印的位数吗? -
关于“问题:如果内存已经超出,其他小数(第 16 位到第 20 位)从哪里来?”:常见的 C 实现使用基于二进制的浮点格式。您看到
double可以存储“15 位小数”的陈述是错误的;它不存储任何小数位。它存储一个基于二进制的数字,本质上是一个与十进制数字几乎没有相关性的实数。当您打印超过 15 位数字时,您会在double中看到有关二进制数字实际值的更多信息。
标签: c floating-point scientific-computing