强制cpp_dec_float向下舍入 [英] Force cpp_dec_float to round down

查看:288
本文介绍了强制cpp_dec_float向下舍入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 .str(n,std :: ios_base :: scientific)打印 ccp_dec_float



我注意到它向上舍入。



我使用 cpp_dec_float 为会计,所以我需要向下舍入。如何做到这一点?

解决方案

它不四舍五入。事实上,它确实是银行家的:看到 Live On Coliru

  #include< boost / multiprecision / number.hpp> 
#include< boost / multiprecision / cpp_int.hpp>
#include< boost / multiprecision / cpp_dec_float.hpp>
#include< iostream>

命名空间mp = boost :: multiprecision;

int main()
{
使用Dec = mp :: cpp_dec_float_50;

(Dec d:{
Dec(3.34),Dec(3.35),Dec(3.38),
Dec(2.24 (-2.28),Dec(-2.28),Dec(-2.28),Dec(-2.28 3.34),Dec( - 3.35),Dec( - 3.38),
})
{
std :: cout< d.str(2,std :: ios_base :: fixed)
<< - ><< d.str(1,std :: ios_base :: fixed)<< \\\
;
}
}

列印:

  3.34  - > 3.3 
3.35 - > 3.4
3.38 - > 3.4
2.24 - > 2.2
2.25 - > 2.2
2.28 - > 2.3
-2.24 - > -2.2
-2.25 - > -2.2
-2.28 - > -2.3
-3.34 - > -3.3
-3.35 - > -3.4
-3.38 - > -3.4

所以如果你想要另一种舍入, p>

以下是一种通用方法( Live On Coliru

  template< int decimals = 0,typename T& 
T round_towards_zero(T const& v)
{
static const T scale = pow(T(10),decimals);

if(v.is_zero())
return v;

//通过ADL找到ceil / floor,并使用表达式模板进行优化
if(v <0)
return ceil(v * scale)
else
//通过ADL找到floor,并使用表达式模板进行优化
return floor(v * scale)/ scale;
}

这可能会由于静态已知的比例因子和使用的Boost Multiprecision库中的表达式模板


I am using .str(n, std::ios_base::scientific) to print ccp_dec_floats.

I've noticed that it rounds up.

I am using cpp_dec_float for accounting, so I need to round downward. How can this be done?

解决方案

It doesn't round up. In fact, it does banker's round: See it Live On Coliru

#include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>

namespace mp = boost::multiprecision;

int main()
{
    using Dec = mp::cpp_dec_float_50;

    for (Dec d : { 
            Dec( "3.34"),   Dec( "3.35"),   Dec( "3.38"),
            Dec( "2.24"),   Dec( "2.25"),   Dec( "2.28"),
            Dec("-2.24"),   Dec("-2.25"),   Dec("-2.28"),
            Dec("-3.34"),   Dec("-3.35"),   Dec("-3.38"),
            })
    {
        std::cout     << d.str(2, std::ios_base::fixed) 
            << " -> " << d.str(1, std::ios_base::fixed) << "\n";
    }
}

Prints:

3.34 -> 3.3
3.35 -> 3.4
3.38 -> 3.4
2.24 -> 2.2
2.25 -> 2.2
2.28 -> 2.3
-2.24 -> -2.2
-2.25 -> -2.2
-2.28 -> -2.3
-3.34 -> -3.3
-3.35 -> -3.4
-3.38 -> -3.4

So if you want another kind of rounding, you'd want to write it explicitly

Here's a generic approach (Live On Coliru)

template <int decimals = 0, typename T>
T round_towards_zero(T const& v)
{
    static const T scale = pow(T(10), decimals);

    if (v.is_zero())
        return v;

    // ceil/floor is found via ADL and uses expression templates for optimization
    if (v<0)
        return ceil(v*scale)/scale;
    else
        // floor is found via ADL and uses expression templates for optimization
        return floor(v*scale)/scale;
}

which hopefully compiles down to optimal code due to statically known scale factor and the use of expression templates in Boost Multiprecision library.

这篇关于强制cpp_dec_float向下舍入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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