1

我尝试检查低于正常的数字。下面是我的代码。它有效,但我看不到最小正正常数和次正常数之间的区别。为什么 ?

/* 
isnormal  example 

ISO C99
http://www.cplusplus.com/reference/cmath/isnormal/
http://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html


compile with: 
gcc -std=c99 -lm s.c

run :
./a.out

*/
#include <stdio.h>      /* printf */
#include <math.h>       /* isnormal, fpclassify */



int TestNumber(double x)
{
  int f; // flag

  f= isnormal(x);
  if (f) 
    printf ("number %f is normal \r",x);
    else printf ("number %.1000f is not normal \n",x);

  return f;

}

//----------------------------

int main()
{

  double d ;
  double MinNormal; 
 int f;
  

  d = 1.0 ; // normal
  f = TestNumber(d);
  do 
  {
   d /=2.0;
   MinNormal=d;
   f = TestNumber(d);
   }
  while (f);

 
  printf ("number %.1000f is minimal normal \n",MinNormal);

  printf ("number %.1000e is not normal \n",d);
  printf ("number %.1000e is minimal normal \n",MinNormal);
  
  
  
  return 0;
}

这是我的输出:

gcc -std=c99 -lm s.c
a@acer:~/cnie/numerical/subnormal/s1$ time ./a.out
number 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111253692925360069154511635866620203210960799023116591527666370844360221740695909792714157950625551028203366986551790550257621708077673005442800619268885941056538899676600116523980507372129181803596078252347125186710418762540332530832907947436024558998429581982425031795438505915243739989044387687497472579022580252545769992829123540932255676896790249605799054288302599621667605717619507439784980479564444580149632075553173315669683173879325651468588102366281589074283217543606141431882102242340570380695573853140084492662205501208072371080928358307527007714254235837645095158066138944836485368656166704349449158753391942346304638698898642932982747054568454770306823378435119933915764534049231 is not normal 
number 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111253692925360069154511635866620203210960799023116591527666370844360221740695909792714157950625551028203366986551790550257621708077673005442800619268885941056538899676600116523980507372129181803596078252347125186710418762540332530832907947436024558998429581982425031795438505915243739989044387687497472579022580252545769992829123540932255676896790249605799054288302599621667605717619507439784980479564444580149632075553173315669683173879325651468588102366281589074283217543606141431882102242340570380695573853140084492662205501208072371080928358307527007714254235837645095158066138944836485368656166704349449158753391942346304638698898642932982747054568454770306823378435119933915764534049231 is minimal normal 
number 1.1125369292536006915451163586662020321096079902311659152766637084436022174069590979271415795062555102820336698655179055025762170807767300544280061926888594105653889967660011652398050737212918180359607825234712518671041876254033253083290794743602455899842958198242503179543850591524373998904438768749747257902258025254576999282912354093225567689679024960579905428830259962166760571761950743978498047956444458014963207555317331566968317387932565146858810236628158907428321754360614143188210224234057038069557385314008449266220550120807237108092835830752700771425423583764509515806613894483648536865616670434944915875339194234630463869889864293298274705456845477030682337843511993391576453404923086054623126983642578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-308 is not normal 
number 1.1125369292536006915451163586662020321096079902311659152766637084436022174069590979271415795062555102820336698655179055025762170807767300544280061926888594105653889967660011652398050737212918180359607825234712518671041876254033253083290794743602455899842958198242503179543850591524373998904438768749747257902258025254576999282912354093225567689679024960579905428830259962166760571761950743978498047956444458014963207555317331566968317387932565146858810236628158907428321754360614143188210224234057038069557385314008449266220550120807237108092835830752700771425423583764509515806613894483648536865616670434944915875339194234630463869889864293298274705456845477030682337843511993391576453404923086054623126983642578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-308 is minimal normal 

================编辑================

应用答案和评论中的所有更改后的好程序

  while (f)
  {
    MinNormal=d;
    d /=2.0;
    f = TestNumber(d);
   }

并仅打印 16 位数字:

printf ( "number %.16e is normal \n",x);
4

1 回答 1

4

循环的编写方式总是以相同的值结束dMinNormal设置为相同的值。您应该将MinNormal更改之前的赋值移动到,d以便它记住d上一次迭代的值。

于 2013-08-04T12:09:55.597 回答