c++ std::ceil(int_x / std::log 2(int_y))是否总是产生准确的结果?

c3frrgcw  于 2023-08-09  发布在  其他
关注(0)|答案(3)|浏览(138)

std::ceil(int_x / std::log2(int_y))是否总是产生准确的结果?或者浮点精度问题会导致xy的某些值偏离1吗?
编辑:我正在专门寻找最简单的方法,我可以 * 准确 * 计算ceil(x * 8 / log2(y))的整数值xy

2q5ifsrm

2q5ifsrm1#

std::ceil(int_x / std::log 2(int_y))是否总是产生准确的结果?
否,不是在结果将与真实的中等价表达式的预期结果相对应的意义上,即使所有值(包括中间值)都在其类型的范围内。
或者,浮点精度问题是否会导致x和y的某些值相差1?
它可以被任何数字。除了浮点表示问题之外,std::log2的精度没有任何标准保证。它不需要是例如数学精确结果中两个最接近的可表示值之一。为此,您必须查看特定C标准库实现的文档。
我在寻找一种最简单的方法
C++20引入了<bit> header,其中包含用于(无符号)整数类型的函数,例如:对比特进行计数、ceil/floor到2的幂、找到最高的设置比特索引等。它们不是基于浮点的,并且具有精确的行为。你可能会想去调查一下。

44u64gxh

44u64gxh2#

std::ceil(int_x / std::log2(int_y))是否总是产生准确的结果?
不。以int_x = 935179272; int_y = 47为例,当用实值log2和实数除法替换std::log2/时,此表达式将不会产生预期的结果(binary64 double)。
这里有一个“简单”但不是很有效的方法来计算这个值。它计算ceil(x / log2(y))的上限和下限,如果它们相等,则返回它们,否则以更高的精度重新计算(使用MPFR)。您可能会发现使用Boost.Multiprecision绑定更容易:

#include <mpfr.h>

unsigned calculate(unsigned x, unsigned y) {
    mp_prec_t prec = 52;

    mpfr_t lo, hi;
    mpfr_init2(lo, prec);
    mpfr_init2(hi, prec);
    unsigned result;

    while (true) {
        mpfr_set_ui(lo, y, MPFR_RNDN);

        int rounding = mpfr_log2(lo, lo, MPFR_RNDD);
        mpfr_set(hi, lo, MPFR_RNDN);
        if (rounding < 0) {
            // Rounded down, the upper bound for log2(y) is the next number
            mpfr_nextabove(hi);
        }

        mpfr_ui_div(hi, x, hi, MPFR_RNDD);
        result = mpfr_get_ui(hi, MPFR_RNDU);  // Lower bound of ceil(x / log2(y))
        mpfr_ui_div(lo, x, lo, MPFR_RNDU);
        unsigned result_hi = mpfr_get_ui(lo, MPFR_RNDU);  // Upper bound
        if (result == result_hi)
            break;

        prec *= 2;
        mpfr_set_prec(lo, prec);
        mpfr_set_prec(hi, prec);
    }

    mpfr_clear(hi);
    mpfr_clear(lo);
    return result;
}

字符串

kr98yfug

kr98yfug3#

n>=x/log2(y)找到最小的整数n等价于用y^n>=2^x找到最小的整数n(当然,假设是y>1)。如果y^n接近2的幂,则可能需要以接近x位的精度计算此表达式。如果你计算出了接近精确结果的东西,你可以用大整数数学计算两个或三个值的y^n,然后取足够大的最小值n

相关问题