如何在 %f 和 %a w/o 之间自动 select 失去精度?

How to automatically select between %f and %a w/o losing precision?

示例代码:

void print_f( float f )
{
   ...
}

int main( void )
{
    print_f( 1.0f );      // prints 1.0
    print_f( 29.0f );     // prints 29.0
    print_f( 29.13f );    // prints 0x1.d2147ap+4
    print_f( 256.0f );    // prints 256.0
    print_f( 256.1f );    // prints 0x1.00199ap+8
    // and so on
    return 0;
}

即如果无法使用 %f 精确打印浮动常量,则使用 %a

问题:“使用%f无法精确打印浮点常量”的条件是什么?

what is the condition for "the floating constant cannot be printed precisely using %f"?

此答案指的是FP常量定义的浮点对象(如double),并非源码原文

当输出 text/string 不返回原始 double 时,字符串不够精确。

如果OP不想尝试各种精度,那么尝试"%f"一次。

void print_f(double x) {
  char buf[1000];
  for (int prec = 0; ; prec++) {
    int len = snprintf(buf, sizeof buf, "%.*f", prec, x);
    if (len < 0 || (unsigned) len >= sizeof buf) break; 
    double y = atof(buf);
    if (x == y) {
      puts(buf);
      return;
    }
  }
  printf("%a\n", x);
}

以上使用线性尝试。重写可以尝试 1,2,4,8,16,.... 然后平分到最小值。


备选方案,printf("%.*g\n", DBL_DECIMAL_DIG, x);接近 OP 的目标,但代码更简单。