如果我有类似的东西:
long x = 1/2;
这不应该四舍五入到1吗?当我在屏幕上打印它时,它会说0。
答案 0 :(得分:29)
它正在进行整数除法,它会截断小数点右边的所有内容。
答案 1 :(得分:6)
整数除法的根源在于数论。当你做1/2时你会问2等于1多少次?答案永远不会,所以方程式变为0 * 2 + 1 = 1,其中0是商(你从1/2得到的),1是余数(从1%2得到的)。
正确地指出,%在数学意义上不是真正的模数,但总是来自除法的余数。处理负整数时会有所不同。
希望有所帮助。
答案 2 :(得分:5)
这个表达式正在做的是它首先声明一个长x的存在,然后为它赋予右侧表达式的值。右侧表达式为1/2,由于1和2都是整数,因此将其解释为整数除法。对于整数除法,结果总是一个整数,所以沿着5/3的行将返回1,因为只有三个符合五。那么1/2,有多少2可以装进1? 0.
如果你写的东西,在某些语言中可以产生一些有趣的输出 double x = 1/2。在这种情况下你可能会期望0.5,但是在分配并将结果转换为double之前,它通常会先评估右边的整数值,给出值0.0
重要的是要注意,在进行这种类型转换时,它永远不会对结果进行舍入。所以,如果你做相反的事情: long x =(long)(1.0 / 2.0); 然后while(1.0 / 2.0)将评估为0.5,(长)强制转换将强制将其截断为0.即使我有长x =(长)(0.9),结果仍然是0.它只是截断小数点后。
答案 3 :(得分:4)
它无法舍入,因为它永远不会处于被舍入的状态
在分配给长
之前,表达式“1/2”永远不会是0.5 现在, long x = 1.0/2.0
因为赋值前右侧的表达式对舍入有效。除非你得到0.499999999999997 ......
答案 4 :(得分:2)
这个问题之前已在本网站上得到解答,如果你想获得0.5使用,你正在进行整数除法:
double x = (double)1/2;
您将获得0.5
的价值。
答案 5 :(得分:1)
有许多不同的舍入约定,最常见的是向+ 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 做给出不同的结果。