当前位置: 首页 > 知识库问答 >
问题:

以sprintf科学记数法打印所有有效数字

董琦
2023-03-14

当R用科学符号将一个大数转换为字符串时,它包括所有有效数字,没有尾随零。有没有可能在C中用Sprintf来完成这个?

> as.character(12345e11)
[1] "1.2345e+15"
> as.character(1234500000e6)
[1] "1.2345e+15"
> as.character(1234500001e6)
[1] "1.234500001e+15"

我尝试了sprintf(buf,“%g”,val),但这似乎最多包含5个十进制数字。我还尝试使用sprintf(buf,“%.18g”,val)设置更高的精度,但这将包括非有效数字和尾随零。

有没有一种方法可以让Sprintf(buf,"%g", val)的行为增加5位数的限制?

共有1个答案

长孙哲
2023-03-14

代码可以使用“%.18e”“%.18g”,但问题是“18”应该有多大?18是最佳值吗?答案在于DBL\u DECIMAL\u DIG

DBL\u DECIMAL\u DIG是要打印的最小有效位数,以确保所有doubledouble字符串往返于相同的double

建议使用格式说明符“%.*e”

请注意,“%.18e”中的“18”是小数点后的有效位数。因此,“%.18e”打印19个有效数字。

使用printf("%a", x);以十六进制输出输出。
对于十进制输出:

#include <float.h>

//    sign + digit +  dp +       digits          + e + sign + expo + \0
char buf[1 + 1 +      1  + (DBL_DECIMAL_DIG - 1) + 1 + 1    + 5    + 1]; 
sprintf(buf, "%.*e", DBL_DECIMAL_DIG - 1, x);

Ref Printf width specifier以保持浮点值的精度

使用典型的doublebinary64格式的像y=1.0/3.0这样的数字需要看到大约53位十进制数字才能看到其精确值。但成功的往返并不需要许多尾随数字。

现在我们知道了要打印的最多数字,使用下面的数字来摆脱那些讨厌的尾随0数字。

#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

char *trim0(double x, char *buf) {
  sprintf(buf, "% .*e", DBL_DECIMAL_DIG - 1, x);
  if (isfinite(x)) {
    char *p = &buf[DBL_DECIMAL_DIG + 1];  // address of last significand digit
    char *t;
    for (t=p; *t == '0'; t--);
    memmove(t+1, p+1, strlen(p+1)+1);
  }
  return buf;
}

int main(void) {
  char buf[1 + 1 + 1 + (DBL_DECIMAL_DIG - 1) + 1 + 1 + 5 + 1];
  printf("%s\n", trim0(1.2, buf));
  printf("%s\n", trim0(1.0/7, buf));
  return 0;
}

输出

 1.2e+00
 1.4285714285714285e-01
 类似资料:
  • 问题内容: 我有一个以指数形式输出的数字: 如何使它以普通格式打印? 问题答案: 您可以将其格式化为定点数字。

  • 如何编写一个递归回溯函数,在该函数中,它打印所有的N位数字,使数字中每3个连续数字的总和正好等于S,其中N小于或等于10,并且是从0到27。 代码: 示例输出: 我很困惑如何递归地写这个。

  • 问题内容: 我想知道如何在具有随机数的数组中的设置值之间打印所有数字。它还应说明有多少用户随机数高于设置值。这是一个外观的示例: 到目前为止,这是我的代码,我设法使其打印出最大的数字。 问题答案: 妳去 我所做的是添加类,而不是生成随机数。 使用可以在需要时分配更多内存的情况下分配更大的内存,以存储小于或大于499的值。 没有新的数组实现摘要: 这是对数组进行迭代并执行以下操作: 计算有500以上

  • 问题内容: 我该如何显示: 十进制(‘40800000000.00000000000000’)为‘4.08E + 10’? 我已经试过了: 但是它有那些额外的0。 问题答案: 在您的“ 40800000000.00000000000000”中,有许多更重要的零,其含义与任何其他数字相同。这就是为什么您必须明确告诉您要在哪里停止的原因。 如果要自动删除所有尾随零,可以尝试:

  • 我想得到用户输入的所有奇数和偶数,然后得到所有奇数的乘积和偶数的差值。例如:输入一个字符串:dfgi456456=';]=34521。输出应该显示用户输入中的所有奇数和偶数以及乘积和差值,在这种情况下,奇数是:5,3,1偶数是:4,6,2奇数的PRODUCT(乘法答案):15偶数的DIFFERENCE(减法答案):-4。请查看我下面的代码。任何帮助都将不胜感激。谢谢。 }

  • 我正在尝试打印剑道网格的所有页面我搜索了很多我使用了这个链接http://docs.telerik.com/KENDO-UI/controls/data-management/grid/walkthrough#printing 注意:链接名称仍然显示为链接,用户可以在打印页面中按它。 我试图使用这个代码来加载所有页面,但它是不工作的,因为它显示打印页面,然后加载网格与所有页面项 我想以友好的布局打