是否可以通过以下方式以科学计数法格式化字符串:
在指数中设置固定位置:1
在尾数中设置固定小数位:0
double number = 123456.789
所以数字应该被格式化
1e+5
我无法为尾数设置 0 个小数点:
cout.precision(0);
cout << scientific << number;
结果:
1.234568e+005
是否可以通过以下方式以科学计数法格式化字符串:
在指数中设置固定位置:1
在尾数中设置固定小数位:0
double number = 123456.789
所以数字应该被格式化
1e+5
我无法为尾数设置 0 个小数点:
cout.precision(0);
cout << scientific << number;
结果:
1.234568e+005
我不知道如何在指数字段中获得一个数字,但以下内容符合您的所有其他要求。
#include <iostream>
#include <iomanip>
int main()
{
const double number = 123456.789;
std::cout << std::setprecision(0) << std::scientific << number << std::endl;
}
输出:
1e+05
编辑:
通过标准(N3291)进行了快速搜索,在使用科学记数法时找不到任何关于指数字段中位数的内容。这可能是实现定义的。
您可以使用{fmt} 格式化库轻松做到这一点:
#include <fmt/core.h>
double number = 123456.789;
auto s = fmt::format("{:.0e}\n", number); // s == "1e+05"
s.erase(s.size() - 2, 1); // s == "1e+5"
基于此库的格式化工具被提议用于 C++20 中的标准化:P0645。
免责声明:我是 {fmt} 的作者。
我不确定您使用的是哪个 C++ 编译器,它会为您提供 3 位指数——C 和 C++ 标准至少需要 2 位数字,这就是 g++ 所做的。使用标准 C 或 C++ I/O 函数无法只获得一位数,因此您必须推出自己的解决方案。由于进行浮点到字符串的转换是一个非常棘手的问题[PDF],我强烈建议不要这样做,而是对结果进行后处理。
这是一种方法:
// C version; you can rewrite this to use std::string in C++ if you want
void my_print_scientific(char *dest, size_t size, double value)
{
// First print out using scientific notation with 0 mantissa digits
snprintf(dest, size, "%.0e", value);
// Find the exponent and skip the "e" and the sign
char *exponent = strchr(dest, 'e') + 2;
// If we have an exponent starting with 0, drop it
if(exponent != NULL && exponent[0] == '0')
{
exponent[0] = exponent[1];
exponent[1] = '\0';
}
}
一旦你有一个字符串,你实际上可以格式化任何东西。更多的 C++ 代码看起来像:
const double number = 123456.789;
const int expSize = 1;
std::ostringstream oss;
std::string output;
oss << std::scientific << number;
unsigned int ePos = oss.str().find("e");
unsigned int dPos = oss.str().find(".");
if(ePos == 0){
//no exponent
}
else if(dPos == 0){
//not decimal
}
else{
output = oss.str().substr(0, dPos) + oss.str().substr(ePos, 2);
if(oss.str().size()-expSize > ePos+1)
output += oss.str().substr(oss.str().size()-expSize, oss.str().size());
else{
//expSize too big (or bug -> e used but no exponent?)
}
std::cout << output;
}
输出:
1e+5
您可以在 expSize 中设置指数大小,这适用于任意大指数。
希望能帮助到你!
这是一个流解决方案:
#include <iostream>
#include <iomanip>
using namespace std;
template<typename T>
struct scientificNumberType
{
explicit scientificNumberType(T number, int decimalPlaces) : number(number), decimalPlaces(decimalPlaces) {}
T number;
int decimalPlaces;
};
template<typename T>
scientificNumberType<T> scientificNumber(T t, int decimalPlaces)
{
return scientificNumberType<T>(t, decimalPlaces);
}
template<typename T>
std::ostream& operator<<(std::ostream& os, const scientificNumberType<T>& n)
{
double numberDouble = n.number;
int eToThe = 0;
for(; numberDouble > 9; ++eToThe)
{
numberDouble /= 10;
}
// memorize old state
std::ios oldState(nullptr);
oldState.copyfmt(os);
os << std::fixed << std::setprecision(n.decimalPlaces) << numberDouble << "e" << eToThe;
// restore state
os.copyfmt(oldState);
return os;
}
使用示例:
int main()
{
double e = 1.234;
cout << scientificNumber(e, 1) << " " << scientificNumber(e, 3);
return 0;
}
输出:
1.2e0 1.234e0