如果 x>=1,那么 1,否则 0,作为纯数学方程?



由于一些开发工具的限制,我正在寻找一个数学表达式:

If x>=1:
y = 1
else:
y = 0

如果简化,X必须是大于等于0的整数。

绝对允许的操作:+, -,/, *, ** (power)

不允许操作:不允许使用绝对值。使用祝辞,& lt; & lt; =,祝辞 ;=, !=, == 是不允许的。使用"if">

For instance不允许:Y =1 *(x>=1)

(由于使用了>=)

对于添加的信息,我试图添加一些约束到谷歌的or-tools,where if X>=0 then, y+=1…

编辑:我正在用python工作。

我想说,没有办法得到一个间断函数到处定义像y(x)使用有限数量的连续函数与组合和连续算子。

你可以得到像abs(x)(x ** 2) ** 0.5这样的东西,但我不知道你如何使用这个(它有一个不连续的一阶导数,但它仍然是连续的)来得到一个完美的阶跃函数,它在每个阶跃点都有指定的值。

0.5 + 0.5 * abs(x-1)/(x-1)这样的东西是你几乎到处都在寻找的,但你会遇到奇点x=1的问题,0/0将被评估。

<标题>

编辑如果输入x保证是整数,那么解决方案很简单:

def y(x):
return 0.5 + 0.5 * abs(x - 0.5) / (x - 0.5)

或者,使用power…定义abs

def y(x):
return 0.5 + 0.5 * ((x - 0.5) ** 2) ** 0.5 / (x - 0.5)

函数对于x=0.5是未定义的,但如果它只对整数求值,这不是问题。

另一个选项是

def y(x):
return 0.5 + abs(x - 0.25) + (x - 0.25) - abs(abs(x-0.25) + (x-0.25) - 0.5)

是一个连续函数,在0.25之前为0,当x从0.25到0.75时线性地从0到1,在它之后保持为1。

在这种情况下,我建议如下:由于x是整数且x>=0,以下逻辑将为真:

ifx > 0then0**x == 0else0**x == 1。这个等于ifx >=1then0**x == 0else0**x == 1.

所以y = 1 - 0**x会给出期望的结果。

让我们看看这里,你基本上有一个不等式x-1>=0

y = (x-1)/abs(x-1)将为您提供除x=0以外的所有情况下您正在寻找的值。在这种情况下,将抛出一个异常,也许您可以使用它来设置y的值。比如:

try{
y=(x-1)/abs(x-1);
} catch(ArithmaticException e){
y = 1}

由于已知整数是非负的,因此可以简单地将整数的所有位逐一或在一起。结果是所需的谓词。如果一个简单的循环执行按位或运算,直到源操作数耗尽为止,则需要进行比较,这是不允许的。

在我现在可以看到的限制下,唯一可行的替代方案是使用直线代码,重复比特提取过程的步骤,因为整数有比特。这就是我在下面的ISO-C99代码中使用的。每个位用DIV和MOD提取,两个一元变量st的OR计算为s + t - s * t。对32位整数的一个简单的详尽测试证实了这种方法是有效的,但是效率显然不是很高。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define OR1(s,t)  (s + t - s * t)
// (x >= 1) ? 1 : 0
uint32_t ge1 (uint32_t x)
{
uint32_t y;
y = OR1 (
OR1 (
OR1 (OR1 (OR1 ((x / 0x00000001) % 2, (x / 0x00000002) % 2),
OR1 ((x / 0x00000004) % 2, (x / 0x00000008) % 2)),
OR1 (OR1 ((x / 0x00000010) % 2, (x / 0x00000020) % 2),
OR1 ((x / 0x00000040) % 2, (x / 0x00000080) % 2))),
OR1 (OR1 (OR1 ((x / 0x00000100) % 2, (x / 0x00000200) % 2),
OR1 ((x / 0x00000400) % 2, (x / 0x00000800) % 2)),
OR1 (OR1 ((x / 0x00001000) % 2, (x / 0x00002000) % 2),
OR1 ((x / 0x00004000) % 2, (x / 0x00008000) % 2)))), 
OR1 (
OR1 (OR1 (OR1 ((x / 0x00010000) % 2, (x / 0x00020000) % 2),
OR1 ((x / 0x00040000) % 2, (x / 0x00080000) % 2)),
OR1 (OR1 ((x / 0x00100000) % 2, (x / 0x00200000) % 2),
OR1 ((x / 0x00400000) % 2, (x / 0x00800000) % 2))),
OR1 (OR1 (OR1 ((x / 0x01000000) % 2, (x / 0x02000000) % 2),
OR1 ((x / 0x04000000) % 2, (x / 0x08000000) % 2)),
OR1 (OR1 ((x / 0x10000000) % 2, (x / 0x20000000) % 2),
OR1 ((x / 0x40000000) % 2, (x / 0x80000000) % 2)))));
return y;
}
int main (void)
{
uint32_t x, res, ref;
x = 0;
do {
res = ge1 (x);
ref = x >= 1;
if (res != ref) {
printf ("error: x=%08x  res=%08x  ref=%08xn", x, res, ref);
return EXIT_FAILURE;
}
x++;
} while (x);
printf ("test passedn");
return EXIT_SUCCESS;
}

对于整数x,如果abs是OK的,那么我建议

y = (x + abs(x)) / (abs(x+1) + abs(x-1))

不受除零的约束,只要不发生溢出,除法对每个整数x都是精确的,无论是正的还是负的,因此可以用整数算术求值。

如果你不关心负x,它甚至更简单:

y = (abs(x+1) - abs(x-1)) / 2

如果函数需要在整个有界整数的域上操作,那么应该使用一些更大的int算法,或者您可以使用float(x)的浮点运算中使用相同的函数,或者同样可以返回到@6502的答案,在这种情况下更简单。

编辑如果你没有绝对值,你可以尝试1-(2.0**(-x))**n,有足够大的n,以利用浮点下溢和/或有限的精度。N =2000应该足以导致每个正整数输入的下溢,但没有必要让N这么高,因为N =100应该足以导致大多数体系结构中的不精确舍入到1。即使使用浮点运算,也很容易有效地计算,您可以使用单次幂1.0-(2.0**(-100.0*x))。对于负整数输入,将x替换为x*x。

相关内容

  • 没有找到相关文章

最新更新