【问题标题】:how to split a float into two integers in C如何在C中将浮点数拆分为两个整数
【发布时间】:2014-03-01 07:47:23
【问题描述】:

下面我正在尝试设置格式说明符,但每次调用该函数时我都想以不同的方式进行设置。关键是打印浮点Data_Ave。在一个实例中,我想要说明符 %2.3f,因此我将传递函数 2 用于 sig_figs_before 和 3 用于 sig_figs_after。在下一个实例中,我想要 %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。我不明白你想要做什么?为什么不直接冲刺fload?有一些方法可以格式化这些。

标签: c format-specifiers


【解决方案1】:

你想要:

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

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

【讨论】:

  • sprintf(msgBody,"%0*.*f ",... 用前导零填充。
【解决方案2】:

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

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

第一行将写,例如(对于 2 和 3)%2.3f 变为 format;第二行将对该格式字符串进行操作以写入msgBody

您还应该考虑使用snprintf 而不是sprintf,尤其是因为您正在使用可能是可变长度的字符串——不想导致buffer overflow

【讨论】:

  • 为此,存在 * 宽度和精度说明符,它们采用 int 参数。无需构造格式。
【解决方案3】:

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 来保留小数点。

注意:这并不限制sig_figs_before 的宽度或数量应该Data_Ave 很大。 @Matt Patenaude 使用 snprintf() 的想法很好。

一种破解方法是测试:

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

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    相关资源
    最近更新 更多