提问人:hash 提问时间:11/9/2023 最后编辑:273Khash 更新时间:11/9/2023 访问量:59
即使将变量从 int 更改为 double 再到 long 后,给定的代码也无法获得更大的值
The given code fails for larger values even after changing variable from int to double to long
问:
这是问题陈述。
*以 10 为底的整数的补码
整数的补码是将所有 0 翻转为 1 以及将所有 1 翻转为 0 时得到的整数。
例如,整数 5 是二进制中的“101”,它的补码是“010”,即整数 2。 给定一个整数 n,返回其 complemet*
我看到了一些使用位掩码解决此问题的解决方案,这是我将要解决的问题,但首先我想知道为什么下面给出的代码不起作用?
它适用于较小的值,但 输入:299475 输出: 224816 预期输出:224812
为了更大的价值,问题似乎仍然存在。
#include <math.h>
class Solution {
#include <math.h>
public:
int bitwiseComplement(int n) {
long a = 0;
int i = 0;
if ( n == 0) {
return 1;
}
while ( n != 0 ) {
int b = n & 1;
if ( b == 1) {
b = 0;
}
else if (b == 0){
b = 1;
}
n = n >> 1;
a = a + (b * pow(10, i));
i++;
}
long sol = 0;
int k = 0;
while ( a != 0) {
int b = a % 10;
sol = sol + (b * pow(2, k));
k++;
a = a/10;
}
return sol;}
};
答:
显然,您正在计算一个数字,其中十进制表示看起来像原始数字的二进制表示。
问题在于这些数字比原始数字大得多(例如,8 得到 1000、16 得到 10000 等)。
1010 已经无法再容纳 32 位(假设 - 有符号或无符号 - 在您的系统上具有该大小)——因此,您可以以这种方式安全转换而不会丢失信息的最大数字是 210 - 1 = 1023,任何更大的数字都会引起溢出——甚至更糟:当您选择有符号整数时,实际上是未定义的行为。int
现在在许多系统上(例如 32 位 linux 或 windows——与 64 位 linux 相比)的大小与 相同,因此在这种情况下也无济于事;您可以尝试改为,或者,因为不必依赖特定于操作系统的大小,请从 header。当时仍然适合的 10 的最大幂是 19,因此您仍然可以计算其表示的最大数字现在是 220 - 1 = 1 048 575。但这仍然很小......long
int
unsigned long long
uint64_t
<cstdint>
现在,相比之下,精度甚至比同等大小的有符号整数差,因为它使用一位作为符号,11 位作为指数,剩下的 52 位作为尾数,所以 53 位作为值,包括隐式的,从而允许精确地表示 1015,因此 216 - 1 = 65535 是您可以计算表示的最大值。double
这个问题的解决方案是跳过以 10 为基数的中间表示,直接计算以 2 为基数的补码:
unsigned int bit = 0;
while(n) // uint32_t!
{
c |= !(n & 1) << bit++; // or 1 - (n & 1), if you prefer...
n >>= 1;
}
评论
pow
pow
~number
int
long
int
long long
uint64_t
cstdint
a = a + b << i
)