Debian系统上的C数学库的GCC实现显然符合(IEEE 754-2008)函数的实现,这意味着舍入应始终是正确的:exp
(来自维基百科)IEEE浮点标准保证加,减,乘,除,融合乘加,平方根和浮点余数将给出无限精度运算的正确舍入结果.对于更复杂的功能,1985年标准中没有给出这样的保证,它们通常只能在最后一点内准确到达.但是,2008标准保证符合要求的实现将给出正确的舍入结果,这些结果遵循主动舍入模式; 但是,函数的实现是可选的.
事实证明,我遇到了这个功能实际上阻碍的情况,因为exp函数的确切结果通常几乎恰好处于两个连续double值(1)之间的中间位置,然后程序进行了大量的进一步计算,失去了速度高达400(!):这实际上是对我的解释(不好问:-S)问题#43530011.
(1)更确切地说,当参数exp变为(2 k + 1)×2 -53,其中k为相当小的整数(例如242)时,就会发生这种情况.特别是,所涉及的计算pow (1. + x, 0.5)倾向于exp使用这样的参数进行调用x,其数量级为2 -44.
由于正确舍入的实现在某些情况下可能非常耗时,我想开发人员也会设计一种方法来获得稍微不那么精确的结果(例如,最多只有0.6 ULP或类似的东西)对于给定范围内的每个参数值(大致)有界限...(2)
......但是怎么做?
(2)我的意思是,我只是不希望像(2 k + 1)×2 -53这样的参数的某些特殊值比相同数量级的大多数值更耗时; 但是我当然不介意参数的某些特殊值是否更快,或者如果大参数(绝对值)需要更大的计算时间.
这是一个显示现象的最小程序:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
int main (void)
{
int i;
double a, c;
c = 0;
clock_t start = clock …Run Code Online (Sandbox Code Playgroud) 当fgetc用于读取流的下一个字符时,通常会检查是否未达到文件结尾
if ((c = fgetc (stream)) != EOF)
Run Code Online (Sandbox Code Playgroud)
哪里c是int类型.然后,文件结束已经达到并且条件将失败,或者c应该是unsigned转换为的char int,预期与EOF-c 不同,因为EOF确保为负.很好......显然.
但是有一个小问题......通常char类型不超过8位,而且int必须至少有16位,所以每个unsigned char都可以表示为int.然而,在这种情况下char会有16或32位(我知道,在实践中情况从来都不是这样......),没有理由为什么人们不能拥有sizeof(int) == 1,所以它(理论上!)可能fgetc (stream)返回EOF(或另一个负值)但文件结尾尚未达到......
我错了吗?如果没有达到文件结尾,C标准中是否会阻止fgetc返回EOF?(如果是的话,我找不到它!).或者if ((c = fgetc (stream)) != EOF)语法不完全可移植?...
编辑:的确,这是问题#3860943的重复.我在第一次搜索时没有找到这个问题.谢谢您帮忙!:-)
我想设计一个函数,它接受可变数量的参数,其中一个参数本身就是一个va_list; 但我的代码出了问题,我不明白...
警告 - 我的问题不是设计代码做我想做的事情(我找到了绕过问题的方法),而只是关于理解我做错了什么......
为了解释我的问题,让我们从一个简单的例子开始:即一个函数ffprintf,它的作用类似于fprintf,但将其内容写入多个字符串,其编号由第一个参数表示的字符串,ffprintf其身份由下一个参数给出(这些参数的数量可能因调用而异,因此您必须使用变量参数列表).这样的函数将使用如下:
FILE *stream0, *stream1, *stream2;
int a, b;
ffprintf (3, stream0, stream1, stream2, "%d divided by %d worths %f", a, b, (double)a / b);
Run Code Online (Sandbox Code Playgroud)
它的代码是:
void ffprintf (int z, ...)
{va_list vlist, auxvlist;
FILE **streams = malloc (z * sizeof(FILE *));
va_start (vlist, z);
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *); // Getting the next stream argument
}
char …Run Code Online (Sandbox Code Playgroud)