Its*_*ret 1 c printf hex type-conversion
我不得不重新实现printf(3)与Cwihtout使用,会做这种转换我的任何功能.
我想后,我明白我做感谢您对球员如何%a工作:如何在%printf语句转换工作?
然后我意识到我不明白这rounding是怎么做的所以我问:C printf浮动四舍五入然后认为我在你帮助我之后就完成了.
而现在这%a完全正常工作,就像我认为的%La那样完全一样,%a但long double由于该男子只说:
修饰语a,A,e,E,f,F,g,G
l(ell)double(忽略,与没有它相同的行为)
L long double
我发现它输出的东西完全不同:'(
double a_double = 0.0001;
long double a_long_double = 0.0001;
printf("%a\n", a_double); #=> 0x1.a36e2eb1c432dp-14
printf("%La\n", a_long_double); #=> 0xd.1b71758e21968p-17
Run Code Online (Sandbox Code Playgroud)
该%a结果总是开头1.,现在我完全不明白什么%La是做.
你能帮我了解的过程是转换0.0001到0xd.1b71758e21968p-17?
编辑:我真的不明白的部分是为什么 %a总是输出一些开头的东西1.而不是%La?
EDIT2:为了更精确:为什么不%a选择输出1. ...p-14和%La选择输出d. ...p-17?
任何(有限的,非零)浮点数都有四个不同的(和有效的)十六进制浮点表示:
并且它们具有连续增加的指数值.你可以使用右移从一个传递到另一个; 这个过程可能会向右移动另一个数字; C标准中没有关于您应该用于%a转换的表示的限制.
使用IEEE float(24位有效数字)或通常的双扩展(64位有效数字,与i386 Linux上的long double一样),由于位数可以被4整除,因此习惯上使用第一种形式作为标准化数字,因为它是使用最少的十六进制数字来完全表示数字的形式(分别在十六进制点之后的5和15位.).
double另一方面,使用IEEE (53位有效数字),在点之后使用第四种形式和13个十六进制数字看起来更好.:因此所有显示的数字实际上代表数据.IEEE quad(形式上为binary128113位有效数字)也会发生同样的情况,该点后面有28个十六进制数字.
这些表示还具有匹配数字的内存中表示的良好属性(这就是为什么通过C99标准中的脚注指导实现的原因.)
如果我们现在看看你的问题,第一个例子(double)符合上面的指导原则,在该点之后有1作为第一个数字,然后是13个十六进制数字.
第二个例子更狡猾.首先将一个double常量存储到一个long double变量中:根据编译器的不同,常量可以舍入到double精度(因为它似乎在这里完成.)这意味着53之后的位将全为零.然后%La根据上面的指导使用转换,从而选择第一个表示,从D开始(二进制1101xxx,与1.A转换为11010xxx); 这里也只有13个十六进制数字,因为编译器丢弃了打印不必要的零(由于舍入.)
请注意,您不能使用printf的%a转换的float.