【发布时间】:2012-04-08 04:27:46
【问题描述】:
如果我有一个奇数,我如何将它一分为二并留下两个整数,第一个比第二个多一个。例如 9 会产生 5 和 4?
【问题讨论】:
-
你的意思是
a / 2和a / 2 + 1? -
如果 1. 数字是偶数(或者永远不需要?)和 2. 如果数字是负数,您是否希望表达式产生正确的答案?
标签: math
如果我有一个奇数,我如何将它一分为二并留下两个整数,第一个比第二个多一个。例如 9 会产生 5 和 4?
【问题讨论】:
a / 2和a / 2 + 1?
标签: math
int x 的“较小的一半”是x/2。 “更大的一半”是x/2 + x%2 或x - x/2。
注意“更小”和“更大”指的是绝对值,所以在负数x的情况下,bigger < smaller。
当然,如果x 总是奇数和正数,那么x%2 将是1,大半部分也可以计算为x/2 + 1。
【讨论】:
x - x/2 对于第二部分会稍微简单一些,因为您刚刚计算了 x/2 ;-)
x%2 优化为寄存器访问。
x / 2 和 x >> 1 不同
这个怎么样?
int a = 9;
int c = a/2;
int b = a-c;
【讨论】:
If I have an odd number。所以,如果是偶数,结果应该是x / 2。
这是我推荐的方式:
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 的唯一警告是,如果输入为负数,则结果将不是预期的。
【讨论】:
floor 和ceil 与浮点输入一起使用。您的输入是整数。
double 运算。如果代码要在没有 FPU 和 math.h 的嵌入式微控制器上执行怎么办?
对于使用微控制器的人来说,/ 和 % 是可怕的成本操作:-)
这显示了另一种方法,使用 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 为负数。
【讨论】:
我认为接受的答案是大致的,但不清楚。如果您想要一些复制和粘贴代码,这将是我眼中的最佳解决方案
var number = 11;
var halfRoundedUp = (number % 2) ? number/2 + .5 : number/2;
var halfRoundedDown = (number % 2) ? number/2 - .5 : number/2;
alert(halfRoundedUp +" "+ halfRoundedDown);
【讨论】: