如何找到TMax不使用移位
How to find TMax without using shifts
Using
! ~ & ^ | +
如何确定32位数字是否为TMax?
TMax是最大的,两个的补数。
到目前为止,我的想法是:
int isTMax(int x)
{
int y = 0;
x = ~x;
y = x + x;
return !y;
}
这只是我尝试过的许多不成功的事情之一,但我就是想不出TMax的一个属性可以让我得到TMax。就像把tmax加到自身上,与所有其他整数相比,它是唯一的。
实际问题如下:
/*
* isTMax - return 1 if x is the maximum, two's complement number,
* and 0 return otherwise.
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTMax(int x) {
int y = 0;
x = ~x;
y = x + x;
return !y;
}
int是32位,所以最大符号可能是0x7FFFFFFF
据我所知,如果不知道有符号类型的最大值并进行直接比较,则无法确定特定值是否为该类型的最大值。这是因为有符号表达式在溢出时会经历未定义的行为。如果你的问题有答案,那就意味着存在一个严重的未解决的问题的答案,这个问题已经在SO上浮动了一段时间:如何通过编程确定给定有符号类型的最大值。
花3个小时做这个问题。我知道这是来自csapp的数据实验室,它的最新要求是
1. Integer constants 0 through 255 (0xFF), inclusive. You are
not allowed to use big constants such as 0xffffffff
....
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
因此,移位算子(<<
/>>
和0x7FFFFFFF
从接受的答案中被禁止)
下面是我的路:
tdd风格:
isTmax(2147483647) == isTmax(0b011111111111...1) == 1
isTmax(2147483646) == isTmax(0b011111111111...0) == 0
isTmax(-1) == isTmax(0b111111111...1) == 0
isTmax(-2147483648) == isTmax(0b100000000...0) == 0
返回值应该是0
或1
。在c语言中,!
对所有非零操作返回0
。因此,!
是必须的,否则,我们不能保证得到所有数字的0
。
第一次朴素尝试:
因为0b0111111...1
(又名2147483647
)是唯一的参数,应该使isTmax
返回1
, 2147483647 + 1
应该是10000000...0
(又名-2147483648
)
0b011111111...1 xor 0b1000000000...0
是0b11111111111...111
。因为我们必须使用!
,所以我们希望看到的是0
(也就是0b0000000000000...0
)。显然,对0b1111111...1
应用逻辑而不是(又称!
),那么我们将得到0b000000000000
):
!(~(x ^ (x + 1))
让我们打印它
void print(int x)
{
printf("%dn", !(~(x ^ (x + 1))));
}
int main() {
print (2147483647);
print(2147483646);
print(-1);
print(-2147483648);
}
1
0
1
0
live demo
还不错,只是-1
不像我们期望的那样工作。
第二次尝试:
比较-1
和2147483647
11111111111111111111111111111111
01111111111111111111111111111111
我们可以找到-1 + 1 = 0
和2147483647 + 1 = -2147483648
。再次强调,我们想要的是diff -1
和2147483647
,因为它们都返回1
,如上所示。回顾c中逻辑not的属性:所有非零将返回0,因此!-2147483648 == 0
和!(-1 + 1) != 0
。只需将x ^ (x + 1)
(x
)的左侧部分修改为x + !(x + 1)
。如果x是2147483647
,则x + !(x + 1)
等于x
。
再次运行:
void print(int x)
{
printf("%dn", !(~( x + !(x + 1) ^ (x + 1))));
}
int main() {
print (2147483647);
print(2147483646);
print(-1);
print(-2147483648);
}
1
0
0
0
live demo
完成了!
int isTmax(int x) {
//add one to x if this is Tmax. If this is Tmax, then this number will become Tmin
//uses Tmin = Tmax + 1
int plusOne = x + 1;
//add to x so desired input becomes 0xFFFFFFFF, which is Umax and also -1
//uses Umax = 2Tmax + 1
x = x + plusOne;
plusOne = !(plusOne);
//is x is 0xffffffff, then this becomes zero when ~ is used
x = ~x;
x = x | plusOne;
x = !x;
return x;
}
无移位解。实现利用!(0b01111 + 1 = 0b10000) = 0
和!(0b11111 + 1 = 0b00000) = 1
的属性是特别棘手的。这道题花了我很长时间。
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
int a = ~((x + 1) ^ x);
int b = !(x + 1);
int c = !(a + b);
return c;
}
也许是这样的?
0x7FFFFFFF是最大正符号32位二进制补码数。int isTMax(int x){
return !(x ^ 0x7FFFFFFF);
}
我不确定,您可能需要将其强制转换为unsigned才能工作
#include <stdio.h>
#include <stdlib.h>
int test(int n) {
return !(n & 0x80000000) & !~(n | (n + 1));
}
// or just effectively do a comparison
int test2(int n) {
return !(n ^ 0x7fffffff);
}
int main(int ac, char **av) {
printf("is%s TMaxn", test(atoi(av[1])) ? "" : " not");
return 0;
}
如果是最高温度:011111…
然后我们用10000....
我们得到11111....
则我们得到所有0 = 0,!0得到1:
int isTmax(int x) {
return !(~((1 << 31) ^ x ));
}
根据最新的要求(即没有移位和没有大常量)给出一个简短的答案。
x + 1 = 0x80000000;
x + (x + 1) = 0xffffffff;
!(~(x + (x + 1))) = 1;
/* Only -1 would fail so we need to explicitly exclude it.*/
最终的答案。
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
int y = x + 1;
return !!(~x) & !(~(x + y));
}
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 如何找出GDB的SIGTRAP核心转储的根本原因
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 找不到QtResource文件中的文件
- Python中的for循环与C++有何不同
- VC++本机单元测试,找不到调试符号
- RegGetValue在当前用户下找不到名称
- 带有 -stdlib=libc++ 的 clang++ 9.0.1 找不到<optional>
- c++找不到具有相同哈希的无序集合元素
- 找不到以下加速库:boost_fiber
- 找不到 FLTK(缺少:FLTK_INCLUDE_DIR)
- 设置 Visual Studio for MPI: 找不到标识符错误
- "assimp/config.h"找不到,但它在文件夹中
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- C++系统找不到指定的文件错误
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",