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

2015-02-24 YongHao Hu 更多博文 » 博客 » GitHub »

原文链接 http://yonghaowu.github.io/2015/02/24/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