For The Best Thing In The World

Work Hard to Enjoy Them. bloom energy

如何用C或者C++使用sprintf在target buffer得到一个QNAN

QNAN wiki上是这样说的:

A QNaN is a NaN with the most significant fraction bit set. QNaN’s propagate freely through most arithmetic operations. These values pop out of an operation when the result is not mathematically defined. (details)[http://en.wikipedia.org/wiki/NaN] 我尝试过sqrt(-1), 1/0, NAN/NAN都不行 结果:

unsigned long nan[2]={0xffffffff, 0x7fffffff};
z = (*(double *)nan);
cout << "z = " << z << "\n";

char temp[100];
sprintf(temp, "%le", z);
printf("temp is %s \n" , temp);

这样子就是解决方法了~ 原理就是 指数二进制全部是1,尾数非0就是NAN, 然后如果尾数最高位是1 就是QNAN 所以上面的数可以随便改很多都行, 比如nan[2]={0xffffffff, 0x7fffff00}. 这是一个很巧妙的方法, 直接修改底层二进制存储方式. 鼎鼎大名的Dragon4算法与最近炙手可热的Grisu算法也是这样做的. 也就是说,你所看到的所有电脑上的小数,都是用到了这个算法显示出来来的.

由此延伸出来的有, 如何判断一个变量是否被赋值了(by QianHong). 通过赋值一个变量NAN值,然后接下来用IsNan()判断它是否NAN, 就可知道它是否被赋值了. 这也是一个很briliant的方法XD