我们有一个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);
}
我尝试使用如下所示,我收到错误,据我所知,我们无法在std::fixed
课程中使用StreamBuffer
。
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();
}
还有其他优化和有效的方法吗?
答案 0 :(得分:8)
StreamBuffer类必须从std :: ios_base(或其某些派生词,如std :: ostream)继承您的预期行为。 std::fixed只能与STL中可用的衍生实现一起使用。
此外,如果您有权访问std :: ios_base,您还可以使用std::ios_base::precision。
如果您遇到无法更新类的情况,那么最常用和传统的方法是通过缩放浮点数。为了减少重复,请查看已经回答的问题here。例如,对于第三度精度,我将所有'value'实例替换为:
select
id,modelname
from
res_reservations
where
resnumber!="9915" and
datestart > now() and
(datestart BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00") or
(dateend BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00") or
(datestart < "2016-02-13 09:00:00" AND dateend >"2016-02-15 09:00:00")
order by id ASC
更好地理解提问者的要求。我已经意识到上述内容不适用于指数。为了解决这个问题,我建议做以下事情:
// 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
然而,这肯定会分配更多的内存。
答案 1 :(得分:6)
只需使用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';
}
答案 2 :(得分:0)