unsigned long long int 参数的日志
log of unsigned long long int argument
我需要在 C++ 代码中进行以下计算:
(((n*log(n)) / log(4)) + 1)
其中 n 的类型为 'unsigned long long int'(并且是 2 的幂,因此结果应为整数)。
对于非常大的数字,我得到一些错误,例如 n = 9007199254740992
结果应该是 238690780250636289
,但是当我 运行 代码时,我得到 238690780250636288
.
这可能是 'log' 函数没有使用 'unsigned long long int' 参数实现的结果吗?如果是这样,有没有办法在不实现新日志功能的情况下规避它?
unsigned long long int upToBit(unsigned long long int n) {
unsigned long long int check = (((n*log(n)) / log(4)) + 1);
return check;
}
Could this be the result of 'log' function not having an implementation with 'unsigned long long int' argument?
是也不是。
您使用 std::log 其中 returns 加倍。由于扩展范围,double 不能表示 238690780250636289。如果您只是将该数字转换为 long long,您将得到完全相同的错误:
int main()
{
volatile double dd = 238690780250636289.0;
printf("%lld\n", (long long)dd);
}
输出:
238690780250636288
要了解为什么会发生这种情况,有 a good paper about floating point numbers。
如果编译器上的 sizeof(long double) > 8,你可能会幸运地使用 long double 版本的 log。您还可以测试 "correctness" 您的计算:
bool resultOk = upToBit(9007199254740992) == 238690780250636289.0;
一般来说,double 有 52 位尾数,由于有额外的隐藏位,double 可以表示的最大可靠整数是 2 的 53 次方或 9007199254740992
。如果您得到的 double 具有更高的整数值,那么有时简单的整数数学 "stops working":
#include <stdio.h>
int main()
{
long long l = 9007199254740992;
double d = (double)l;
d += 1;
printf("9007199254740992 + 1 = %lld\n", (long long)d);
}
输出:
9007199254740992 + 1 = 9007199254740992
我需要在 C++ 代码中进行以下计算:
(((n*log(n)) / log(4)) + 1)
其中 n 的类型为 'unsigned long long int'(并且是 2 的幂,因此结果应为整数)。
对于非常大的数字,我得到一些错误,例如 n = 9007199254740992
结果应该是 238690780250636289
,但是当我 运行 代码时,我得到 238690780250636288
.
这可能是 'log' 函数没有使用 'unsigned long long int' 参数实现的结果吗?如果是这样,有没有办法在不实现新日志功能的情况下规避它?
unsigned long long int upToBit(unsigned long long int n) {
unsigned long long int check = (((n*log(n)) / log(4)) + 1);
return check;
}
Could this be the result of 'log' function not having an implementation with 'unsigned long long int' argument?
是也不是。
您使用 std::log 其中 returns 加倍。由于扩展范围,double 不能表示 238690780250636289。如果您只是将该数字转换为 long long,您将得到完全相同的错误:
int main()
{
volatile double dd = 238690780250636289.0;
printf("%lld\n", (long long)dd);
}
输出:
238690780250636288
要了解为什么会发生这种情况,有 a good paper about floating point numbers。 如果编译器上的 sizeof(long double) > 8,你可能会幸运地使用 long double 版本的 log。您还可以测试 "correctness" 您的计算:
bool resultOk = upToBit(9007199254740992) == 238690780250636289.0;
一般来说,double 有 52 位尾数,由于有额外的隐藏位,double 可以表示的最大可靠整数是 2 的 53 次方或 9007199254740992
。如果您得到的 double 具有更高的整数值,那么有时简单的整数数学 "stops working":
#include <stdio.h>
int main()
{
long long l = 9007199254740992;
double d = (double)l;
d += 1;
printf("9007199254740992 + 1 = %lld\n", (long long)d);
}
输出:
9007199254740992 + 1 = 9007199254740992