用C(非标准格式)将浮点数转换为科学计数法?

时间:2013-09-29 20:52:02

标签: c format point floating scientific-notation

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

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

例如:3349.25应为“3.34925乘以10次幂3”

2 个答案:

答案 0 :(得分: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),除法会在结果中引入一些错误,而我没有用小数字或负数测试它,但这应该给你一些东西给你从...开始。

答案 1 :(得分:2)

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

double很多问题,现有函数已经很好地处理了字符串转换。 (INF,Nan,-0,舍入,否定)。使用frexp()power()的OP通常会在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