سؤال

انا استخدم .str(n, std::ios_base::scientific) لطباعة ccp_dec_floatس.

لقد لاحظت أنه يتم تقريبه.

انا استخدم cpp_dec_float لأغراض المحاسبة، لذا أحتاج إلى التقريب للأسفل.كيف يمكن القيام بذلك؟

هل كانت مفيدة؟

المحلول

لا يتم تقريبه.في الواقع، إنها تقوم بجولة مصرفية:شاهده العيش على كوليرو

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

مطبوعات:

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

لذا، إذا كنت تريد نوعًا آخر من التقريب، فأنت تريد كتابته بشكل صريح

إليك نهج عام (العيش على كوليرو)

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

والذي نأمل أن يتم تجميعه إلى الكود الأمثل نظرًا لعامل القياس المعروف بشكل ثابت واستخدام قوالب التعبير في مكتبة Boost Multiprecision.

نصائح أخرى

أفترض أنك تحاول تحقيق التقريب إلى نقطة عشرية معينة، أليس كذلك؟

التقريب القياسي

double rounding_func(double in, double precision){
   return round(in*pow(10,precision))/pow(10,precision);              
}

ولكن كما يشير عنوانك، فأنت تحاول إجباره على التقريب إلى الرقم الأدنى، لذا فكر في الأمر

double rounding_func(double in, double precision){
   return floor(in*pow(10,precision))/pow(10,precision);              
}

حظ سعيد!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top