double precision - pow()
double precision - pow()
我想计算[n^(1/k)],其中n
是long long
和2 <= k <= lg(n)
;k是整数。
我想也许我可以用这个:
long long d = pow(n,1.0/k)-1;
while(power(d,k) < n)
d++;
d--;
但是它可能在最后一步溢出CCD_ 4。
如果我写:,是否保证d
将是pow(n,1.0/k)四舍五入
long long d = long long(pow(n,1.0/k));
如果没有,什么是容易的&计算floor(pow(n,1.0/k))
的安全方法
如果不确切了解stdlib中pow
的实现,您就不能绝对确定
floor(pow(n,1.0/k)) or (long long)pow(n,1.0/k)
返回正确的结果。1.0/k
引入了小的不准确性,并且加上pow
的不准确度(由于double
s的表示而不可避免),如果n
是k
第次方或非常接近1,则pow()
的结果可能刚好移动超过整数阈值。
使用Haskell的(**)
的示例,它与math.h
中的pow()
做相同的事情,但它可能有不同的实现:
Prelude> 3^37-1 :: Int
450283905890997362
Prelude> fromIntegral it ** (1.0/37)
3.0000000000000004
然而,它至少总是非常接近正确的结果,因此如果必要,您可以将其作为快速校正的起点。
// assumes k > 2
long long r = (long long)pow(n,1.0/k);
while (n/power(r+1,k-k/2) >= power(r+1,k/2)) ++r;
while (n/power(r,k-k/2) < power(r,k/2)) --r;
其中power(a,b)
是整数幂函数(例如可以是round(pow(a,b))
或通过重复平方求幂)。通过将r
和r+1
分别提高到k-1
第次方,可以避免溢出(除非r
为1,否则您可以在必要时通过测试k < 64 && n < (1ull << k)
轻松处理这种特殊情况)。
当然,在floor(pow(n,1.0/k))
以上的情况下,对特殊情况和修复的测试会花费时间,几乎所有情况下都不会做任何事情,所以这可能不值得。
您要求担保。不幸的是,对于C/C++中的类型,几乎没有什么保证。虽然您会发现long long
通常是64位,但这些数据类型的确切大小尚未定义。然而,我相信1.0
默认情况下是float
,它通常具有32位。float pow(float base, float exponent)
和double pow(double base, double exponent)
都有,我不确定C++是否会理解你想要使用哪一个,除非你指定了它。因此,你在转换时可能会失去精度。哦,顺便说一句,即使是double
也可能不如long long
精确,因为它也存储指数。
另一个问题是,即使你认为浮点转换不应该精确,它也可能是不精确的。我有过这样的例子,我从stdin
将一个整数读取到浮点变量中,然后立即将其转换回int
,发现它是从一个整数值四舍五入到下面的值!为了避免这种情况,您应该在类型转换之前添加一个小的epsilon。ε的大小应该根据变量的精度和您使用的数字的大小来确定。
pow()返回一个双精度,我认为这就是您错过的
- 在C++中如何在没有pow的情况下进行基础计算
- 理解GCC中的std::pow实现
- 子例程,不使用 pow,并带有参数和返回
- 整数溢出,最大值为 pow(10,19)
- 在 while 循环中使用 pow() 函数 C++
- 在C++不使用 POW 的情况下处理负指数
- C++ 中 pow() 函数的输出没有给出准确的答案
- 没有匹配'pow'功能
- 为什么 while ((i <= 9) && square == pow(i, 2)) { cou
- Arduino Pow() 和 Armstrong 数问题
- 在 c++ 中使用 cout.precision() 的奇怪输出
- C++在不使用pow或循环的情况下计算一个数字的幂
- 让constexpr在OSX上的C++17中使用pow
- Why (int)pow(2, 32) == -2147483648
- 错误:"int pow(double,int)"与上一个声明int pov(double a,int
- Pow 在 C++ 中无法按预期工作
- C++使用负矢量大小计算的 pow 行为
- 在C++中使用 pow() 时出错
- 为什么"possible lack of precision"不是编译器错误?
- double precision - pow()