小编Ed *_*ynn的帖子

为什么Knuth使用这个笨重的减量?

我正在看一些Don Knuth教授的代码,用CWEB编写,转换为C.具体的例子是dlx1.w,可从Knuth的网站获得

在一个阶段,struct nd [cc]的.len值递减,并且以一种笨重的方式完成:

  o,t=nd[cc].len-1;
  o,nd[cc].len=t;
Run Code Online (Sandbox Code Playgroud)

(这是一个特定于Knuth的问题,所以也许你已经知道"o"是一个预处理器宏,用于递增"mems",这是通过访问64位字来衡量的累计工作量.) "t"中剩余的值绝对不会用于其他任何事情.(此处的示例位于dlx1.w的第665行,或者是ctangle之后的dlx1.c的第193行.)

我的问题是:为什么Knuth这样写,而不是

nd[cc].len--;
Run Code Online (Sandbox Code Playgroud)

他确实在其他地方使用过(dlx1.w第551行):

oo,nd[k].len--,nd[k].aux=i-1;
Run Code Online (Sandbox Code Playgroud)

(而"oo"是一个类似的宏,用于递增"mems"两次 - 但这里有一些细微之处,因为.len和.aux存储在相同的64位字中.为S.len和S分配值. aux,通常只计算mems的一个增量.)

我唯一的理论是减量包括两个内存访问:首先查找,然后分配.(这是正确的吗?)这种写作方式提醒了这两个步骤.这对于Knuth来说会非常冗长,但也许这是一种本能的备忘录,而不是说教.

为了它的价值,我在没有找到答案的情况下搜索了CWEB文档.我的问题可能更多地与Knuth的标准实践有关,我正在逐渐采用.我会对这些实践被布局(并且可能被批评)作为一个块的任何资源感兴趣 - 但是现在,让我们关注为什么Knuth以这种方式编写它.

c knuth increment literate-programming decrement

12
推荐指数
1
解决办法
235
查看次数

为什么 long double 的精度不比 double 更高?

我想检查 C 中各种浮点类型可以保存的最大整数而不损失精度。这是一个测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <float.h>

#define FLOATTYPE long double
#define ONE ((FLOATTYPE)1.0)
#define TWO ((FLOATTYPE)2.0)

  int
main(int argc,char*argv[]){
  int i;
  FLOATTYPE x;

  x = ONE;
  for(i=0;;++i){
    printf("1.0<<%3d: x=%.0Lf",i,(long double)x);
    if((x+ONE)!=x &&
       (x+ONE)- x == ONE){
      printf(" ... can increment without loss of precision\n");
    }else{
      printf(" ... cannot increment without loss of precision\n");
      break;
    }
    x *= TWO;
  }

  printf("FLT_RADIX = %d\n",FLT_RADIX);
  printf("FLT_MANT_DIG = %d\n",FLT_MANT_DIG);
  printf("DBL_MANT_DIG = %d\n",DBL_MANT_DIG);
  printf("LDBL_MANT_DIG = %d\n",LDBL_MANT_DIG);
  printf("\nsizeof(FLOATTYPE) = %lu\n",sizeof(x));
}
Run Code Online (Sandbox Code Playgroud)

一些结果(使用gcc-9(Ubuntu 9.4.0-1ubuntu1~16.04)9.4.0): …

c double long-double windows-subsystem-for-linux

3
推荐指数
1
解决办法
249
查看次数