“长x = 1/2”等于1还是0,为什么?

如果我有类似的东西:

long x = 1/2; 

这不应该四舍五入到1? 当我在屏幕上打印时,它会说0。

它正在进行整数除法,它会截断小数点右边的所有内容。

整数除法的根源在于数论。 当你做1/2时你会问2等于1多少次? 答案永远不会,因此等式变为0 * 2 + 1 = 1,其中0是商(从1/2得到的),1是余数(从1%2得到的)。

指出%在数学意义上不是真正的模数,但总是来自除法的余数。 处理负整数时有区别。

希望有所帮助。

这个表达式正在做的是它首先声明一个长的叫x的存在,然后为它赋予右侧表达式的值。 右侧表达式为1/2,由于1和2都是整数,因此将其解释为整数除法。 对于整数除法,结果总是一个整数,所以沿着5/3的行将返回1,因为只有三个符合五。 那么1/2,有多少2可以装进1? 0。

如果你写一些像double x = 1/2的东西,这可以在某些语言中产生一些有趣的输出。 在这种情况下你可能会期望0.5,但是在分配并将结果转换为double之前,它通常会先评估右边的整数值,给出值0.0

重要的是要注意,在进行这种类型转换时,它永远不会对结果进行舍入。 所以如果你做相反的事情:长x =(长)(1.0 / 2.0); 然后,当(1.0 / 2.0)将评估为0.5时,(长)强制转换将强制将其截断为0.即使我有长x =(长)(0.9),结果仍然是0.它只是截断小数点后。

它不能圆,因为它永远不会处于圆形状态

在分配给long之前,表达式“1/2”从不是0.5

现在, long x = 1.0/2.0因为在赋值之前右边的表达式对于舍入是有效的。 除非你得到0.499999999999997 ……

这个问题之前已在本网站上得到解答,你正在进行整数除法,如果你想得到0.5的用法:

 double x = (double)1/2; 

你会得到0.5的值。

有许多不同的舍入约定,最常见的是向+ inf舍入,向-inf舍入并向零舍入。 很多人都认为有一种正确的方法,但他们都对这种方式有不同的看法;-)

整数除法没有中间非整数结果,但当然除法是确定性地完成的,并且对于特定平台和编译器将始终遵循一个特定的舍入约定。

使用Visual C ++,我得到5/2 = 2和-5/2 = -2,向零舍入。

C,C ++和Java中的舍入通常称为“截断” – 意味着丢弃不需要的位。 但这可能会产生误导。 使用4位2s补码二进制,做截断意味着给…

  5/2 = 0101/0010 = 0010.1 --> 0010 = 2 -5/2 = 1011/0010 = 1101.1 --> 1101 = -3 

这是围绕-infinity,这是Python做的(或至少它在Python 2.5中做了什么)。

如果我们使用符号幅度表示,截断将是正确的词,但是二十几岁的补充已经成为事实上的标准。

在C和C ++中,我预计虽然它通常被称为截断,但实际上这个细节在标准中是未定义的并留给实现 – 允许编译器使用最简单和最快的平台方法的借口(处理器分区指令是什么)自然而然)。 这只是一个问题,如果你有负数 – 我还没有看到任何语言或实现会给5/2 = 3。

我不知道Java标准是什么。 Python手册指定了“floor”除法,这是舍入到-infinity的常用术语。

编辑

额外的注意事项 – 根据定义,如果a / b = c余数d,则a =(b * c)+ d。 为此,您必须选择余数来满足您的舍入约定。

人们倾向于认为余数和模数是相同的,但WRT签署的值,它们可以是不同的 – 取决于舍入规则。 模数值根据定义从不为负数,但余数可能为负数。

我怀疑Python round-towards-negative-infinity规则旨在确保单个%运算符作为余数和模数有效。 在C和C ++中,%表示(余数或模数)是(是的,你猜对了)实现定义。

Ada实际上有两个独立的操作符 – mod和rem。 需要将除法舍入为零,以便mod和rem 确实给出不同的结果。