在 C 中设置最高有效位
set most significant bit in C
我正在尝试设置 long long unsigned x 中的最高有效位。
为此,我使用了这行代码:
x |= 1<<((sizeof(x)*8)-1);
我认为这应该可行,因为 sizeof 以字节为单位给出大小,所以我乘以 8 并减去 1 来设置最后一位。每当我这样做时,编译器都会发出警告:"warning: left shift count >= width of type"
我不明白为什么会出现这个错误。
使用 1ULL << 而不是 1 <<
仅使用“1”就可以移动一个整数。 1ULL 将是一个 unsigned long long,这正是您所需要的。
整数可能是 32 位,long long
可能是 64 位宽。所以转移:
1 << ((sizeof(long long)*8)-1)
将(最有可能):
1 << 63
由于 1 是一个整数(很可能)是 32 位,因此您会收到警告,因为您正试图移过 32 位值的 MSB。
您要移动的文字 1
不会自动成为 unsigned long long
(而是 int
),因此没有您需要的位数。用 ULL
作为后缀(即 1ULL
),或者在转换之前将其转换为 unsigned long long
以使其成为正确的类型。
此外,为了让陌生平台更安全一些,请将 8
替换为 CHAR_BIT
。请注意,这仍然不一定是设置最高有效位的最佳方法,例如,参见 this question 了解替代方案。
如果您假设 unsigned long long
具有特定宽度,您还应该考虑使用 uint64_t
等类型,或者如果您需要 uint_fast64_t
/uint_least64_t
至少一定的宽度,或者 uintmax_t
如果你需要最大的可用类型。
您正在移动的 1
是一个 int
类型的常量,这意味着您正在将 int
值移动 sizeof(unsigned long long) * 8) - 1
位。这种偏移很容易超过 int
的宽度,这显然是您的情况。
如果你想获得一些 unsigned long long
类型的位掩码掩码,你应该从 unsigned long long
类型的初始位掩码开始,而不是 int
类型。
1ull << (sizeof(x) * CHAR_BIT) - 1
可以说构建相同掩码的更好方法是
~(-1ull >> 1)
或
~(~0ull >> 1)
由于负整数的 2 的补码表示,最负整数正是仅设置 MSB 的所需位模式。所以 x |= (unsigned long long )LONG_LONG_MIN;
也应该有效。
我正在尝试设置 long long unsigned x 中的最高有效位。 为此,我使用了这行代码:
x |= 1<<((sizeof(x)*8)-1);
我认为这应该可行,因为 sizeof 以字节为单位给出大小,所以我乘以 8 并减去 1 来设置最后一位。每当我这样做时,编译器都会发出警告:"warning: left shift count >= width of type"
我不明白为什么会出现这个错误。
使用 1ULL << 而不是 1 <<
仅使用“1”就可以移动一个整数。 1ULL 将是一个 unsigned long long,这正是您所需要的。
整数可能是 32 位,long long
可能是 64 位宽。所以转移:
1 << ((sizeof(long long)*8)-1)
将(最有可能):
1 << 63
由于 1 是一个整数(很可能)是 32 位,因此您会收到警告,因为您正试图移过 32 位值的 MSB。
您要移动的文字 1
不会自动成为 unsigned long long
(而是 int
),因此没有您需要的位数。用 ULL
作为后缀(即 1ULL
),或者在转换之前将其转换为 unsigned long long
以使其成为正确的类型。
此外,为了让陌生平台更安全一些,请将 8
替换为 CHAR_BIT
。请注意,这仍然不一定是设置最高有效位的最佳方法,例如,参见 this question 了解替代方案。
如果您假设 unsigned long long
具有特定宽度,您还应该考虑使用 uint64_t
等类型,或者如果您需要 uint_fast64_t
/uint_least64_t
至少一定的宽度,或者 uintmax_t
如果你需要最大的可用类型。
您正在移动的 1
是一个 int
类型的常量,这意味着您正在将 int
值移动 sizeof(unsigned long long) * 8) - 1
位。这种偏移很容易超过 int
的宽度,这显然是您的情况。
如果你想获得一些 unsigned long long
类型的位掩码掩码,你应该从 unsigned long long
类型的初始位掩码开始,而不是 int
类型。
1ull << (sizeof(x) * CHAR_BIT) - 1
可以说构建相同掩码的更好方法是
~(-1ull >> 1)
或
~(~0ull >> 1)
由于负整数的 2 的补码表示,最负整数正是仅设置 MSB 的所需位模式。所以 x |= (unsigned long long )LONG_LONG_MIN;
也应该有效。