1

我需要将浮点数转换为以下非标准格式:“浮点数 F(标准十进制指数格式),后跟字符串乘以 10 的幂,然后是整数 K。”

有没有办法从 e% 或类似于 frexp() 的函数中提取指数?

例如:3349.25 应该是“3.34925 乘以 10 的 3 次方”

4

2 回答 2

3

你可以很容易地自己实现一个十进制等价的 frexp 。您需要的代码如下所示:

int exponent = (int)log10(fabs(d));
double mantissa = d / pow(10, exponent);
printf("%f X 10^%d\n", mantissa, exponent);

首先,我们通过取数字绝对值的以 10 为底的对数来确定指数。(我们需要fabs,因为log10需要一个肯定的论点。)演员向零舍入,这很方便,是我们需要的。然后我们通过除法来归一化尾数。

这不处理 d==0(或无穷大或 NaN),除法会在结果中引入一些错误,而且我还没有用小数或负数对其进行测试,但这应该会给你一些起点。

于 2013-09-29T21:39:15.450 回答
2

printf()我喜欢使用这种格式的 OP 方法 let"%e"来完成繁重的工作。

现有函数已经很好地处理了字符串转换的许多问题。double(INF,Nan,-0,四舍五入,负数)。OP 的使用frexp()power()通常在接近 10 次方的值附近会遇到舍入和有限精度的问题。

仅给出 1 个示例,OP 对精确度的了解是模糊的。 power(0.5, 100)需要100位数字。让我们将其限制为 DBL_DIG,而不是使用%e默认值 6。(实际上是 7 位,在 DP 之后仅 6 位。)

char *Heyhey_Notation(char *dest, double x) {
  static const char Times[] = " times 10 to the power ";
  char buffer[3 + DBL_DIG + sizeof(Times) + 20 + 1];

  sprintf(buffer, "%.*e", DBL_DIG, x);
  char *e = strchr(buffer, 'e');  // find exponent position
  if (e) {
    char *zero = e;
    while (zero[-1] == '0') zero--; 
    *zero = '\0'; // OP wants excess zeros trimmed.
    int power = atoi(&e[1]);  // trim excess zeros by converting to int
    sprintf(dest, "%s%s%d", buffer, Times, power);
    }
  else {
    strcpy(dest, buffer);
  }
  return dest;
}

int main() {
  char buf[100];
  puts(Heyhey_Notation(buf, 3349.25));
  puts(Heyhey_Notation(buf, -0.0));
  puts(Heyhey_Notation(buf, 123));
  puts(Heyhey_Notation(buf, -1234567890.0/9999999999.0));
  puts(Heyhey_Notation(buf, -1/0.0));
  puts(Heyhey_Notation(buf, atof("nan")));
  return 0;
}

3.34925 times 10 to the power 3
-0. times 10 to the power 0
1.23 times 10 to the power 2
-1.234567890123457 times 10 to the power -1
-inf
nan
于 2013-09-29T23:02:05.760 回答