如何在不使用 c 中的关系运算符的情况下 return true 或 false?
How to return true or false without using the relational operators in c?
娱乐一下,假设我们要用c语言比较格式为double
的两个数字,而我们只能使用使用算术运算符+, -, *, /, %
和[=13=的数学方程式] 和 pow()
以检查等于 (==
)、小于 (<
) 和大于 (>
)。与真正的关系运算符 ==, <, and >
类似,我们编写的代码必须 return True (1
) 或 False (0
) 用于每种不同类型的检查。
例如,没有使用除+, -, *, /, %
和fabs()
和pow()
以外的任何其他运算符,如果我们确定两个变量a
和 b
相等,我们应该 return True 或 1,否则,return False 或 0。最好是 return 整数 0 和 1 而不是布尔值 True 和 False。更复杂的是,我们不能使用真正的关系运算符、逻辑运算符、位运算符或任何其他运算符。此外,我们不能使用 switch 语句或条件语句。如何操作?
我知道如何求x和y中较小的值,也就是说x < y
可以计算为((x + y) + fabs(x-y))/2
。进一步,要找到x > y
,就是((x + y) - fabs(x-y))/2
。但是,这些方程 return 值 x 或 y 取决于比较方程,我需要它们 return 0 或 1。同样,我需要一些代码方程 return 是 0 或1 如果 x 和 y 彼此相等 (==
),并且必须仅使用 +, -, *, /, %
和 fabs()
和 pow()
.
任何给定的运算符 +, -, *, /
,应用于 double
操作数将导致 double
,以及 fabs()
和 pow()
函数。因此无法仅使用提供的运算符和 fabs()
和 pow()
函数将 double
转换为 integer
。
此外,%
运算符仅适用于整数。有一个 fmod()
函数,它为浮点数提供相同的功能。
我们可以实现我们的计算结果,仅使用提供的运算符和函数将以相同的方式在内存中表示为整数 0 和 1。
例如,这些函数是为 float
制作的,即 32 位浮点数:
float largerOf(float x, float y){
return ((x + y) + fabs(x-y)) / 2.0;
}
float smallerOf(float x, float y){
return ((x + y) - fabs(x-y)) / 2.0;
}
int isEqual(float x, float y){
float tmp = smallerOf(x, y) / largerOf(x, y);
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return *((int*)(&tmp));
}
int lessThan(float x, float y){
float tmp = smallerOf(x, y) / x;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
int greaterThan(float x, float y){
float tmp = smallerOf(x, y) / y;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
这个解决方案使用了这样一个事实,即两个值中较小的值除以两个值中的较大值将导致小于或等于 1.0
的值。然后,当且仅当第一次除法的结果恰好为 1.0
时,除法后的结果值再次除以两个硬编码常量,以尝试获得最右边位设置的浮点数。毕竟,我们访问内存,包含浮点数,就好像它包含整数结果一样。
请注意,此解决方案未经过充分测试,可能会以多种不同方式出现问题。例如,值 2.0
和 1.9999993
表现良好,但是 2.0
和 1.9999994
被认为是相等的,尽管 32 位浮点数可以表示值 1.9999993
和1.9999994
并且它们都与 2.0
不同。
娱乐一下,假设我们要用c语言比较格式为double
的两个数字,而我们只能使用使用算术运算符+, -, *, /, %
和[=13=的数学方程式] 和 pow()
以检查等于 (==
)、小于 (<
) 和大于 (>
)。与真正的关系运算符 ==, <, and >
类似,我们编写的代码必须 return True (1
) 或 False (0
) 用于每种不同类型的检查。
例如,没有使用除+, -, *, /, %
和fabs()
和pow()
以外的任何其他运算符,如果我们确定两个变量a
和 b
相等,我们应该 return True 或 1,否则,return False 或 0。最好是 return 整数 0 和 1 而不是布尔值 True 和 False。更复杂的是,我们不能使用真正的关系运算符、逻辑运算符、位运算符或任何其他运算符。此外,我们不能使用 switch 语句或条件语句。如何操作?
我知道如何求x和y中较小的值,也就是说x < y
可以计算为((x + y) + fabs(x-y))/2
。进一步,要找到x > y
,就是((x + y) - fabs(x-y))/2
。但是,这些方程 return 值 x 或 y 取决于比较方程,我需要它们 return 0 或 1。同样,我需要一些代码方程 return 是 0 或1 如果 x 和 y 彼此相等 (==
),并且必须仅使用 +, -, *, /, %
和 fabs()
和 pow()
.
任何给定的运算符 +, -, *, /
,应用于 double
操作数将导致 double
,以及 fabs()
和 pow()
函数。因此无法仅使用提供的运算符和 fabs()
和 pow()
函数将 double
转换为 integer
。
此外,%
运算符仅适用于整数。有一个 fmod()
函数,它为浮点数提供相同的功能。
我们可以实现我们的计算结果,仅使用提供的运算符和函数将以相同的方式在内存中表示为整数 0 和 1。
例如,这些函数是为 float
制作的,即 32 位浮点数:
float largerOf(float x, float y){
return ((x + y) + fabs(x-y)) / 2.0;
}
float smallerOf(float x, float y){
return ((x + y) - fabs(x-y)) / 2.0;
}
int isEqual(float x, float y){
float tmp = smallerOf(x, y) / largerOf(x, y);
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return *((int*)(&tmp));
}
int lessThan(float x, float y){
float tmp = smallerOf(x, y) / x;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
int greaterThan(float x, float y){
float tmp = smallerOf(x, y) / y;
tmp /= 3.4028235E38;
tmp /= 4194303.9999999997;
return (*((int*)(&tmp)))-isEqual(x,y);
}
这个解决方案使用了这样一个事实,即两个值中较小的值除以两个值中的较大值将导致小于或等于 1.0
的值。然后,当且仅当第一次除法的结果恰好为 1.0
时,除法后的结果值再次除以两个硬编码常量,以尝试获得最右边位设置的浮点数。毕竟,我们访问内存,包含浮点数,就好像它包含整数结果一样。
请注意,此解决方案未经过充分测试,可能会以多种不同方式出现问题。例如,值 2.0
和 1.9999993
表现良好,但是 2.0
和 1.9999994
被认为是相等的,尽管 32 位浮点数可以表示值 1.9999993
和1.9999994
并且它们都与 2.0
不同。