【问题标题】:How to divide an odd number to leave two integers?如何将一个奇数除以留下两个整数?
【发布时间】:2012-04-08 04:27:46
【问题描述】:

如果我有一个奇数,我如何将它一分为二并留下两个整数,第一个比第二个多一个。例如 9 会产生 5 和 4?

【问题讨论】:

  • 你的意思是a / 2a / 2 + 1
  • 如果 1. 数字是偶数(或者永远不需要?)和 2. 如果数字是负数,您是否希望表达式产生正确的答案?

标签: math


【解决方案1】:

int x 的“较小的一半”是x/2。 “更大的一半”是x/2 + x%2x - x/2

注意“更小”和“更大”指的是绝对值,所以在负数x的情况下,bigger < smaller

当然,如果x 总是奇数和正数,那么x%2 将是1,大半部分也可以计算为x/2 + 1

【讨论】:

  • x - x/2 对于第二部分会稍微简单一些,因为您刚刚计算了 x/2 ;-)
  • @DavidHeffernan:好点,添加了它。我确实相信 x86 上的整数除法总是会在寄存器中产生模数,因此智能编译器可能会将 x%2 优化为寄存器访问。
  • 不太可能与性能相关,您仍然必须执行添加,就像我的版本一样。
  • @mouviciel:“这只是右移”——假设是无符号类型。由于向零舍入,有符号类型还有更多内容。在此示例中,我们可能知道该值将始终为正,因此无关紧要,但如果编译器不知道这一点,那么即使它愿意,也无法进行该转换。
  • @mouviciel 表示负整数,x / 2x >> 1 不同
【解决方案2】:

这个怎么样?

int a = 9;
int c = a/2;
int b = a-c;

【讨论】:

  • 但如果 a 是偶数,则结果不是我们想要的。
  • @Richard Number 根据问题是奇数。
  • 规范表明a是奇数。
  • @DavidHeffernan 问题指出If I have an odd number。所以,如果是偶数,结果应该是x / 2
  • @RichardJ.RossIII 问题表明输入是奇数。再读一遍。
【解决方案3】:

这是我推荐的方式:

int low = floor(x / 2.0f);
int high = ceil(x / 2.0f);

我发现它比x/2 + x%2 版本更简洁。 此版本还受益于这样一个事实,即如果您碰巧使用偶数运行它,输出将是正确的。

编辑:

人们似乎抱怨我对整数使用浮点数,这是一个完全基于位的版本:

int a = 9;

int b = a >> 1;
int c = b | (a & 0x1);

#2 的唯一警告是,如果输入为负数,则结果将不是预期的。

【讨论】:

  • -1 您将floorceil 与浮点输入一起使用。您的输入是整数。
  • 如果这是你能做到的最好的要求,那就不要了。如果您坚持使用浮点数来解决应该纯粹使用整数算术执行的问题,则不会。
  • 整数运算不应使用double 运算。如果代码要在没有 FPU 和 math.h 的嵌入式微控制器上执行怎么办?
  • @RichardJ.RossIII 我不关心性能,将 FP 数学用于可以想象的最琐碎的整数运算是没有意义的。如果我永远不允许这段代码通过代码审查。
  • 比特旋转更糟糕!只是为了上帝的爱使用适当的算术运算符!这是可以想象的最简单的编程问题。
【解决方案4】:

对于使用微控制器的人来说,/%可怕的成本操作:-)

这显示了另一种方法,使用 shift >>&,它们有时更便宜:

#include <stdio.h>

int main (int argc, const char * argv[]) {
    const int iplus = 9;
    const int iminus = -9;

    printf("iplus=%d iminus=%d\n", iplus, iminus);

    printf("(iplus >> 1)=%d ((iplus >> 1) + (iplus & 1))=%d\n", iplus >> 1, (iplus >> 1) + (iplus & 1));
    printf("(iminus >> 1)=%d ((iminus >> 1) + (iminus & 1))=%d\n", iminus >> 1, (iminus >> 1) + (iminus & 1));

    return 0;
}

输出:

iplus=9 iminus=-9
(iplus >> 1)=4 ((iplus >> 1) + (iplus & 1))=5
(iminus >> 1)=-5 ((iminus >> 1) + (iminus & 1))=-4

据此Does either ANSI C or ISO C specify what -5 % 10 should be?

C89 和 C99 之间 / 的行为有所不同,特别是带有一个负数的 C89 '/ 可能返回正数或负数结果,但 C99 为负数。

【讨论】:

    【解决方案5】:

    我认为接受的答案是大致的,但不清楚。如果您想要一些复制和粘贴代码,这将是我眼中的最佳解决方案

    var number = 11;
    var halfRoundedUp = (number % 2) ? number/2 + .5 : number/2;
    var halfRoundedDown = (number % 2) ? number/2 - .5 : number/2;
    alert(halfRoundedUp +" "+ halfRoundedDown);
    

    【讨论】:

      猜你喜欢
      • 2016-01-06
      • 2016-02-26
      • 1970-01-01
      • 2016-03-16
      • 2013-10-06
      • 2010-10-14
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多