如何防止数字以科学记数法显示
how to prevent numbers from showing up in scientific notations
我们有一个StreamBuffer
类,我们没有实现std::fixed
运算,我试图防止数字出现在科学记数法中。使用我下面的代码,一些数字以科学记数法显示。我们希望避免进行任何分配,因此出于性能原因,我们实现了StreamBuffer
类。
下面是代码:
T value = 0;
template<typename U> void process(U& buf, DataOption holder) const {
if (holder == DataOption::TYPES) {
switch (type_) {
case teck::PROC_FLOAT:
buf << "{"float":" << value << "}";
break;
case teck::PROC_DOUBLE:
buf << "{"double":" << value << "}";
break;
default:
buf << "{"" << type_ << "":" << value << "}";
}
}
}
这就是它的称呼方式:
void HolderProcess::dump(std::ostream& os, DataOption holder) const
{
process<std::ostream>(os, holder);
}
void HolderProcess::dump(StreamBuffer& buffer, DataOption holder) const
{
process<StreamBuffer>(buffer, holder);
}
我尝试使用如下所示,但出现一个错误,我知道我们不能在我的StreamBuffer
类上使用std::fixed
。
case teck::PROC_DOUBLE:
buf << "{"double":" << std::fixed << value << "}";
我可以在这里使用的std::fixed
的替代方案是什么,它根本不进行任何分配。我正在考虑将数字转换为字符串,然后在其上应用std::fixed
,但这也会进行一些分配,我想避免这种情况。
执行此操作的最佳方法是什么,它既能提高性能,又不进行任何分配?我有一个以下解决方案,但它会做一些分配,因为它使用字符串。我可以从上面的代码调用下面的方法。
template <typename T> string str(T number)
{
std::ostringstream ss;
ss << std::fixed << number;
return ss.str();
}
还有其他优化和有效的方法吗?
StreamBuffer 类必须继承自 std::ios_base(或它的一些衍生物,如 std::ostream(才能实现预期行为。 std::fixed 只能与作为 STL 一部分的衍生实现一起使用。
此外,如果您可以访问 std::ios_base,您还可以使用 std::ios_base::p recision。
如果您遇到无法更新类的情况,那么最常用和最传统的方法是通过缩放浮点数。为了减少重复,请在此处查看已经回答的问题。例如,对于 3rd 精度,我会将所有"值"实例替换为:
// case teck::PROC_FLOAT:
static_cast<float>( static_cast<int>(value*1000) ) / 1000
// case techk::PROC_DOUBLE:
static_cast<double>( static_cast<long long>(value*1000) ) / 1000
更好地了解提问者的要求。我已经意识到上述内容不适用于指数。为了解决这个问题,我建议执行以下操作:
case teck::PROC_FLOAT:
std::stringstream ss;
ss << std::fixed << value;
buf << "{"float":" << ss.str() << "}";
break;
但是,这肯定会分配更多内存。
只需使用 snprintf:
#include <cstdio>
#include <limits>
#include <iostream>
int main() {
double value = 0.1234567890123456789;
const int Precision = std::numeric_limits<double>::digits10;
const std::size_t StringBufferSize = Precision + 3; // sign, dot and terminating zero.
char str[StringBufferSize];
std::snprintf(str, StringBufferSize - 1, "%.*f", Precision, value);
str[StringBufferSize - 1] = 0;
// buf << "{"double":" << str << "}";
std::cout << str << 'n';
}
,也许你应该尝试CppFormat。这里有一些如何使用它进行格式化的示例。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 防止主数据类型C++的隐式转换
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 字符串-C++后显示的随机字符
- 继承期间显示未知行为的子类
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 将指针设置为"nullptr"并不能防止双重删除?
- 程序崩溃并显示"std::out_of_range"错误
- 如何防止C++遗留代码中的挂起指针
- Python中的for循环与C++有何不同
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 为什么在C的循环中使用printf的Rust代码不显示输出,而在C++的循环中显示std::cout
- 如何防止显示 QMessageBox 时出现双槽调用
- 如何防止数字以科学记数法显示
- Qt:隐藏然后显示QQuickView防止未来的鼠标事件
- 防止在调用SDL_SetVideoMode后显示窗口
- MFC -消息框显示,主窗口有一个取消按钮.消息框处于活动状态时防止取消
- 我们如何防止控制台窗口显示在Visual Studio下