std::ceil(int_x / std::log2(int_y))是否总是产生准确的结果?或者浮点精度问题会导致x和y的某些值偏离1吗?编辑:我正在专门寻找最简单的方法,我可以 * 准确 * 计算ceil(x * 8 / log2(y))的整数值x和y。
std::ceil(int_x / std::log2(int_y))
x
y
ceil(x * 8 / log2(y))
2q5ifsrm1#
std::ceil(int_x / std::log 2(int_y))是否总是产生准确的结果?否,不是在结果将与真实的中等价表达式的预期结果相对应的意义上,即使所有值(包括中间值)都在其类型的范围内。或者,浮点精度问题是否会导致x和y的某些值相差1?它可以被任何数字。除了浮点表示问题之外,std::log2的精度没有任何标准保证。它不需要是例如数学精确结果中两个最接近的可表示值之一。为此,您必须查看特定C标准库实现的文档。我在寻找一种最简单的方法C++20引入了<bit> header,其中包含用于(无符号)整数类型的函数,例如:对比特进行计数、ceil/floor到2的幂、找到最高的设置比特索引等。它们不是基于浮点的,并且具有精确的行为。你可能会想去调查一下。
std::log2
<bit>
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绑定更容易:
int_x = 935179272; int_y = 47
/
double
ceil(x / log2(y))
#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; }
字符串
kr98yfug3#
用n>=x/log2(y)找到最小的整数n等价于用y^n>=2^x找到最小的整数n(当然,假设是y>1)。如果y^n接近2的幂,则可能需要以接近x位的精度计算此表达式。如果你计算出了接近精确结果的东西,你可以用大整数数学计算两个或三个值的y^n,然后取足够大的最小值n。
n>=x/log2(y)
n
y^n>=2^x
y>1
y^n
3条答案
按热度按时间2q5ifsrm1#
std::ceil(int_x / std::log 2(int_y))是否总是产生准确的结果?
否,不是在结果将与真实的中等价表达式的预期结果相对应的意义上,即使所有值(包括中间值)都在其类型的范围内。
或者,浮点精度问题是否会导致x和y的某些值相差1?
它可以被任何数字。除了浮点表示问题之外,
std::log2
的精度没有任何标准保证。它不需要是例如数学精确结果中两个最接近的可表示值之一。为此,您必须查看特定C标准库实现的文档。我在寻找一种最简单的方法
C++20引入了
<bit>
header,其中包含用于(无符号)整数类型的函数,例如:对比特进行计数、ceil/floor到2的幂、找到最高的设置比特索引等。它们不是基于浮点的,并且具有精确的行为。你可能会想去调查一下。44u64gxh2#
std::ceil(int_x / std::log2(int_y))
是否总是产生准确的结果?不。以
int_x = 935179272; int_y = 47
为例,当用实值log2和实数除法替换std::log2
和/
时,此表达式将不会产生预期的结果(binary64double
)。这里有一个“简单”但不是很有效的方法来计算这个值。它计算
ceil(x / log2(y))
的上限和下限,如果它们相等,则返回它们,否则以更高的精度重新计算(使用MPFR)。您可能会发现使用Boost.Multiprecision绑定更容易:字符串
kr98yfug3#
用
n>=x/log2(y)
找到最小的整数n
等价于用y^n>=2^x
找到最小的整数n
(当然,假设是y>1
)。如果y^n
接近2的幂,则可能需要以接近x
位的精度计算此表达式。如果你计算出了接近精确结果的东西,你可以用大整数数学计算两个或三个值的y^n
,然后取足够大的最小值n
。