如何在C语言中将一个浮点数分成两个整数

4

以下我尝试设置格式说明符,但每次调用函数时我想以不同的方式进行。重点是要打印浮点数Data_Ave。在一个实例中,我想要说明符%2.3f,因此我会将sig_figs_before设为2,将sig_figs_after设为3。在下一个实例中,我想要%1.4f,所以我会传递这些整数。

char * Send_Data(float Data[10], const char* SUBJECT_SEND_NAME, char *Data_Backup, int sig_figs_before, int sig_figs_after)
{
  float Data_Ave = ((Data[0] + Data[1] + Data[2] + Data[3] + Data[4] +
            Data[5] + Data[6] + Data[7] + Data[8] + Data[9])/10);
  sprintf(msgBody,"%%i.%if, ", before_decimal, after_decimal, Data_Ave);
  ... //Some more code
  }

我相信这样做不会起作用,所以我考虑将浮点数拆分为两个整数,并像这样打印:
sprintf(msgBody,"%i.%i, ", int_value, decimal_value);

但我不知道如何正确地分割浮点数。有什么建议吗?


这样不会起作用。考虑一下"2.03",它将导致before_decimal=2、after_decimal=3并组合成2.3。 我不明白你想做什么?为什么不直接sprintf浮点数呢?有办法格式化这些。 - usr1234567
3个回答

5

你希望:

sprintf(msgBody,"%*.*f, ", before_decimal+after_decimal+1, after_decimal, Data_Ave);

请注意,您可以使用*通过整数参数指定宽度。另外请注意,在格式%N.Mf中,N是打印数字的总大小(包括小数、点、符号、指数、填充等等),而M是小数精度。这就是为什么,在您的情况下,第一个数字应该是before_decimal+after_decimal+1而不仅是before_decimal


1
或者使用sprintf(msgBody,"%0*.*f ",...来填充前导零。 - staticd

2

您可以使用sprintf两次来获得想要的结果 - 首先获取格式字符串,然后再次获取实际结果。

sprintf(format, "%%%i.%if", before_decimal, after_decimal);
sprintf(msgBody, format, Data_Ave);

第一行将写入格式为%2.3f(对于2和3)到format; 第二行将操作该格式字符串以写入msgBody
您还应考虑使用snprintf而不是sprintf,特别是因为您正在使用潜在的可变长度字符串-不想引起缓冲区溢出

1
为此,存在 * 宽度和精度限定符,它们需要一个 int 参数。无需构造格式。 - Jens

0

sprintf() 不提供“有效数字前”。

它提供一个最小字段宽度,可以从sig_figs_beforesig_figs_after和值本身中派生出来。

char * Send_Data(float Data[10], const char* SUBJECT_SEND_NAME, 
    char *Data_Backup, int sig_figs_before, int sig_figs_after) {

  assert(sig_figs_before >= 1);
  assert(sig_figs_after >= 0);

  float Data_Ave = ((Data[0] + Data[1] + Data[2] + Data[3] + Data[4] +
                     Data[5] + Data[6] + Data[7] + Data[8] + Data[9])/10);

  int width = sig_figs_before + 1 + sig_figs_after;  // +1 for '.'
  // Make room for '-'
  if (Data_Ave < 0) width++;
  sprintf(msgBody, "%#*.*f, ", width, sig_figs_after, Data_Ave);
}

'#'被用于sig_figs_after == 0以保留小数点。

注意:如果Data_Ave很大,这不会限制sig_figs_before的宽度或数量。@Matt Patenaude 使用snprintf()的想法是好的。

一个hack方法是测试:

if (log10(fabs(Data_Ave)+0.5) > sig_figs_before) UseAlternativePrint();   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接