【问题标题】:C printf optional decimal placesC printf 可选小数位
【发布时间】:2020-06-02 21:33:20
【问题描述】:

在 C# 中,我可以执行以下操作:

Console.Write("{0}, ", string.Format("{0:0.00###########}", someFloatValue));

为某个任意浮点值获取至少 2 位小数,直到某些可选的小数位数,在本例中为 13。

我想知道 C 语言中的 printf 是否也可以这样做?

【问题讨论】:

  • 这能回答你的问题吗 -> stackoverflow.com/a/35121056/1737811 ?
  • @mutantkeyboard 问题不在于指定变量的精度。
  • “可选小数位”是什么意思?这是否意味着它将打印 2-13 位小数,但省略尾随零?
  • 如果这就是你的意思,没有内置的东西可以做到这一点。有关解决方法,请参阅 stackoverflow.com/questions/277772/…
  • for(char *end = buf + sprintf(buf, "%.*f", prec, val) - 1; end > buf && *end == '0'; --end) *end = '\0'; 将打印 valbufprec 小数,然后丢弃尾随的 0。 C 中没有内置的浮点格式可以(可靠地)做到这一点。

标签: c printf


【解决方案1】:

去掉尾随的零位。

void formatDouble(char* buf, double val, int precMin, int precMax) {
  int length = sprintf(buf, "%.*f", precMax, val);
  if (isfinite(val) && length > 0) {
    for (int i = precMax; i > precMin; i--) {
      if (buf[length - 1] == '0') {
        buf[--length] = '\0';
      } else {
        break;
      }
    }
  }
}

void fooo(double d) {
  char buf[100];
  formatDouble(buf, d, 2,6);
  printf("<%s>\n", buf);
}

int main(void) {
  fooo(0.1234567890);
  fooo(0.123450);
  fooo(0.12300);
}

输出

<0.123457>
<0.12345>
<0.123>

【讨论】:

  • 如果我删除 buf[length - i - 1] 并且只使用 buf[i] 就可以了。
  • @JohnErnest 代码已修改。
【解决方案2】:

感谢提供一些指导的链接。这是我想出的,它允许您指定最小和最大精度,因此它的行为更像 C# 函数,以及对最后一位数字进行四舍五入。让我知道是否应该进行一些优化或更改。

void formatDouble(char* buf, double val, int precMin, int precMax) {
    sprintf(buf, "%.*f", precMax, val);
    int startpos = 0;
    int length = strlen(buf);
    bool found = false;
    for (int z = 0; z < length; z++)
    {
        if (buf[z] == '.')
        {
            startpos = z;
            found = true;
            break;
        }
    }
    if (!found)
        return;
    int endIndex = startpos + precMin;
    found = false;
    for (int z = precMax + startpos; z >= startpos + precMin; z--)
    {
        if (buf[z] >= '1' && buf[z] <= '9')
        {
            endIndex = z;
            if (endIndex < startpos + precMax)
            {
                // Round Digit
                if (buf[z + 1] >= '5')
                    buf[z]++;
            }
            found = true;
            break;
        }
    }
    for (int z = endIndex + 1; z <= length; z++)
    {
        if (z <= startpos + precMax)
            buf[z] = 0;
    }
}

【讨论】:

  • if (buf[z + 1] &gt;= '5')double rounding,因为 val 被四舍五入为文本,然后此代码再次四舍五入。
猜你喜欢
  • 2022-11-18
  • 2013-05-01
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
相关资源
最近更新 更多