将科学记数法的字符串格式化为十进制

时间:2013-07-09 11:20:16

标签: math io c++-cli

我有一个类似“2.1648797E -05”的字符串,我需要格式化它以转换为“0.00021648797”

是否有任何解决方案可以进行此转换

5 个答案:

答案 0 :(得分:2)

尝试使用doublelong long

cout << setiosflags(ios::fixed) << thefloat << endl;

浮点的一个重要特征是,对于较大的值,它们没有与所有有效数字相关联的精度回到小数点。 “科学”展示合理地反映了固有的内部存储现实。

答案 1 :(得分:0)

C++中,您可以使用std::stringstream首先打印数字,然后将其读取为double,然后使用格式说明符将其打印,以将数字的准确度设置为12位数。请查看this问题,了解如何以固定精度打印十进制数。

答案 2 :(得分:0)

如果你真的只是从字符串表示到字符串表示并且精度非常重要或者值可能会留下双精度的有效范围,那么我将避免转换为double。 由于精度错误或范围问题,您的价值可能会因此而改变。

尝试编写一个简单的文本解析器。大致相同: 读取数字,省略小数点直到“E”,但存储小数点位置。 在'E'之后将指数读作数字并将其添加到存储的小数位。 然后再次输出数字,在开头或结尾正确附加零并插入小数点。

答案 3 :(得分:-1)

谢谢你们,我用它来修复它:

Decimal dec = Decimal.Parse(str, System.Globalization.NumberStyles.Any);

答案 4 :(得分:-1)

这里有不明确的问题 1.“2.1648797E -05”中的空格是否有意,让我们假设它没问题 2. 2.1648797E-05比0.00021648797小10倍。假设OP意味着“0.000021648797”(另一个零) 3. Windows未标记,但OP发布了Windows答案。

这里面临的主要挑战,我认为OP的核心问题是std::precision()fixeddefault中有不同的含义,OP希望default含义为fixed

精度字段在fixed和默认浮点表示法之间不同。默认情况下,精度字段指定在小数点之前和之后显示的最大有用位数,可以使用科学计数法,而在fixed中,精度字段指定小数点后要显示的位数


解决此问题的两种方法:将输入字符串更改为数字,然后以新的固定空间格式输出数字 - 如下所示。第二种方法是解析输入字符串并形成新格式 - 这里没有完成。

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cmath>
#include <cfloat>

double ConvertStringWithSpaceToDouble(std::string s) {
  // Get rid of pesky space in "2.1648797E -05"
  s.erase (std::remove (s.begin(), s.end(), ' '), s.end());
  std::istringstream i(s);
  double x;
  if (!(i >> x)) {
    x = 0; // handle error;
  }
  std::cout << x << std::endl;
  return x;
}

std::string ConvertDoubleToString(double x) {
  std::ostringstream s;
  double fraction = fabs(modf(x, &x));
  s.precision(0);
  s.setf(std::ios::fixed);
  // stream whole number part
  s << x << '.';
  // Threshold becomes non-zero once a non-zero digit found.
  // Its level increases with each additional digit streamed to prevent excess trailing zeros.
  double threshold = 0.0;
  while (fraction > threshold) {
    double digit;
    fraction = modf(fraction*10, &digit);
    s << digit;
    if (threshold) {
      threshold *= 10.0;
    }
    else if (digit > 0) {
      // Use DBL_DIG to define number of interesting digits
      threshold = pow(10, -DBL_DIG);
    }
  }
  return s.str();
}

int main(int argc, char* argv[]){
  std::string s("2.1648797E -05");
  double x = ConvertStringWithSpaceToDouble(s);
  s = ConvertDoubleToString(x);
  std::cout << s << std::endl;
  return 0;
  }