用基本算术运算实现相等函数

时间:2016-02-01 21:37:12

标签: math arithmetic-expressions integer-arithmetic

给定正整数输入xy,如果1 == x和{{1},是否存在将返回y的数学公式}} 除此以外?我处于不幸的位置,不得不使用只允许我使用以下符号的工具:数字0 - 0;小数点9;括号.(;以及四个基本算术运算)+-/

目前我依赖于评估除零的工具为零的事实。 (我无法判断这是一个错误还是一个功能。)因此,我可以使用*。显然,这是丑陋和不理想的,特别是在它是一个错误的情况下,他们会在未来的版本中修复它。

3 个答案:

答案 0 :(得分:1)

利用C中的整数除法截断为0,以下效果很好。没有乘法溢出。为所有“正整数输入module ApplicationHelper # Returns the full title on a per-page basis. def full_title(page_title = '') base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else page_title + " | " + base_title end end end x”定义良好。

<强> y

(x/y) * (y/x)

输出(与#include <stdio.h> #include <limits.h> void etest(unsigned x, unsigned y) { unsigned ref = x == y; unsigned z = (x/y) * (y/x); if (ref != z) { printf("%u %u %u %u\n", x,y,z,ref); } } void etests(void) { unsigned list[] = { 1,2,3,4,5,6,7,8,9,10,100,1000, UINT_MAX/2 , UINT_MAX - 1, UINT_MAX }; for (unsigned x = 0; x < sizeof list/sizeof list[0]; x++) { for (unsigned y = 0; y < sizeof list/sizeof list[0]; y++) { etest(list[x], list[y]); } } } int main(void) { etests(); printf("Done\n"); return 0; } 无差异)

x == y

答案 1 :(得分:1)

如果除法是截断且数字不是太大,那么:

((x - y) ^ 2 + 2) / ((x - y) ^ 2 + 1) - 1

如果x = y则除法值为2,否则截断为1。

(此处x ^ 2是x * x的缩写。)

如果(x-y)^ 2溢出,则会失败。在这种情况下,您需要独立核对x/k = y/kx%k = y%k,其中(k-1)*(k-1)不会溢出(如果k为ceil(sqrt(INT_MAX)),则会有效)。 x%k可以x-k*(x/k)计算,A&&B只需A*B

这适用于[-k*k, k*k]范围内的任何x和y。

稍微不正确的计算,使用大量中间值,假设x - y不会溢出(或至少溢出不会产生假0)。

  int delta = x - y;
  int delta_hi = delta / K;
  int delta_lo = delta - K * delta_hi;
  int equal_hi = (delta_hi * delta_hi + 2) / (delta_hi * delta_hi + 1) - 1;
  int equal_lo = (delta_lo * delta_lo + 2) / (delta_lo * delta_lo + 1) - 1;
  int equals = equal_hi * equal_lo;

或完整写出:

((((x-y)/K)*((x-y)/K)+2)/(((x-y)/K)*((x-y)/K)+1)-1)*
((((x-y)-K*((x-y)/K))*((x-y)-K*((x-y)/K))+2)/
 (((x-y)-K*((x-y)/K))*((x-y)-K*((x-y)/K))+1)-1)

(对于有符号的31位整数,使用K = 46341;对于无符号的32位整数,使用65536。)

使用@ chux的测试工具进行检查,添加0个案例:live on coliru并使用负值also on coliru

在整数减法可能产生2s补码环绕以外的平台上,可以使用类似的技术,但将数字分成三部分而不是两部分。

答案 2 :(得分:0)

所以问题是如果他们将除法修正为零,则意味着你不能再使用包含输入变量的任何除数(你必须检查除数!= 0,并且实现该检查将解决原始xy == 0问题!);因此,根本不能使用除法。

因此,只能使用+-*和关联运算符()。不难看出只有这些操作符才能实现所期望的行为。