如何防止数字出现在科学记数法 [英] how to prevent numbers from showing up in scientific notations

查看:187
本文介绍了如何防止数字出现在科学记数法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个 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\:<<值<< };
break;
case teck :: PROC_DOUBLE:
buf<< {\double\:<值<< };
break;
默认值:
buf<< {\<< type_<<\:<值<< };
}
}
}

正在调用:

  void HolderProcess :: dump(std :: ostream& os,DataOption holder)const 
{
process< std :: ostream>(os,holder);
}

void HolderProcess :: dump(StreamBuffer& buffer,DataOption holder)const
{
process< streamBuffer>
}

我尝试使用如下所示,我们不能在我的 StreamBuffer 类上使用 std :: fixed

  case teck :: PROC_DOUBLE:
buf<< {\double\:< std :: fixed<<值<< };

std :: fixed的替代方法我可以在这里使用,根本不做任何分配。我正在想把数字转换为字符串,然后应用 std :: fixed 它,但会做一些分配,我想避免这样。



这是最好的方法是性能高效,不做任何分配?我有一个下面的解决方案,但它会做一些分配,因为它使用字符串。我可以从我上面的代码调用下面的方法。

 模板< typename T> string str(T number)
{
std :: ostringstream ss;
ss<< std :: fixed<<数;
return ss.str();
}

有没有其他优化和高效的方法?

$ b $ StreamBuffer类必须继承std :: ios_base(或其某些派生类,如std :: ostream),以满足您的预期行为。 std :: fixed 只能处理作为STL一部分可用的衍生实现。



此外,如果您可以访问std :: ios_base,您还可以使用 std :: ios_base :: precision



如果你遇到无法更新类的情况,使用和传统的方式是通过缩放浮动。为了减少重复,请查看此处已回答的问题。例如,对于第三个精度,我将替换所有的'值'实例:

  // 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<<值;
buf<< {\float\:<< ss.str()<< };
break;

但是,这将分配更多的内存。





We have a StreamBuffer class in which we haven't implemented std::fixed operations and I am trying to prevent number showing up in scientific notations. With my below code some numbers are getting shown in scientific notations. We want to avoid doing any allocations so that's why we implemented StreamBuffer class because of performance reason.

Below is the code:

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 << "}";
        }
    }
}

And this is the way it is being called:

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);
}

I tried using like as shown below and I got an error by which I understood we cannot use std::fixed on my StreamBuffer class.

case teck::PROC_DOUBLE:
    buf << "{\"double\":" << std::fixed << value << "}";

What is the alternative to std::fixed I can use here which doesn't do any allocations at all. I was thinking of converting number to string and then apply std::fixed on it but that will do some allocations as well which I want to avoid that.

What is the best way to do this which is performance efficient and doesn't do any allocations? I have a below solution but it will do some allocations as it uses string. I can call below method from my above code.

template <typename T> string str(T number)
   {
       std::ostringstream ss;
       ss << std::fixed << number;
       return ss.str();
   }

Is there any other optimized and efficient way?

解决方案

StreamBuffer class must inherit from std::ios_base (or some of it's derivatives such as std::ostream) for your expected behaviour. std::fixed can only work with derivative implementations of what is available as part of the STL.

Additionally, if you have access to an std::ios_base, you can also play around with std::ios_base::precision.

If you are stuck in a situation where you cannot update the class then the most commonly used and traditional way is by way of scaling floats. In the interest of reducing duplication please have a look at the already answered question here. For example, for a 3rd degree of precision, I'd replace all 'value' instances with:

// 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

Having better understood the questioner's requirements. I have realised that the above would not work with exponents. In order to get around this I propose doing the following:

case teck::PROC_FLOAT:
        std::stringstream ss;

        ss << std::fixed << value;
        buf << "{\"float\":" << ss.str() << "}";
        break;

This, however, will most certainly allocate more memory.


这篇关于如何防止数字出现在科学记数法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆