是“长x=1/2”吗?等于1或0,为什么?
如果我有这样的事情:
long x = 1/2;
这不应该四舍五入到 1 吗?当我在屏幕上打印它时,它显示0。
if I have something like:
long x = 1/2;
shouldn't this be rounded up to 1? When I print it on the screen it say 0.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它正在进行整数除法,即截断小数点右侧的所有内容。
It's doing integer division, which truncates everything to the right of the decimal point.
整数除法起源于数论。当你做 1/2 时,你是在问 2 等于 1 有多少次?答案是否定的,因此方程变为 0*2 + 1 = 1,其中 0 是商(从 1/2 得到的结果),1 是余数(从 1%2 得到的结果)。
正确指出 % 不是数学意义上的真正模数,而始终是除法的余数。处理负整数时存在差异。
希望有帮助。
Integer division has its roots in number theory. When you do 1/2 you are asking how many times does 2 equal 1? The answer is never, so the equation becomes 0*2 + 1 = 1, where 0 is the quotient (what you get from 1/2) and 1 is the remainder (what you get from 1%2).
It is right to point out that % is not a true modulus in the mathematical sense but always a remainder from division. There is a difference when you are dealing with negative integers.
Hope that helps.
这个表达式的作用是首先声明一个名为 x 的 long 的存在,然后将右侧表达式的值赋给它。右侧表达式是 1/2,由于 1 和 2 都是整数,因此被解释为整数除法。对于整数除法,结果始终是整数,因此 5/3 之类的内容将返回 1,因为五中只有一个三。那么对于 1/2,1 可以容纳多少个 2? 0.
如果您编写类似的内容,这在某些语言中可能会产生一些有趣的输出
双 x = 1/2。在这种情况下,您可能期望 0.5,但在分配并将结果转换为 double 之前,它通常会先计算右侧的整数值,给出值 0.0
需要注意的是,在进行这种类型转换时,它会永远不要对结果进行四舍五入。所以如果你做相反的事情:
长 x = (长)(1.0/2.0);
然后,虽然 (1.0/2.0) 将计算为 0.5,但 (long) 转换将强制将其截断为 0。即使我有 long x = (long)(0.9),结果仍然为 0。它只是截断小数点后。
What this expression is doing is it first declares the existence of a long called x, and then assigning it the value of the right hand side expression. The right hand side expression is 1/2, and since 1 and 2 are both integers this is interpreted as integer division. With integer division the result is always an Integer, so something along the lines of 5/3 will return 1, as only one three fits in a five. So with 1/2, how many 2s can fit into 1? 0.
This can in some languages result in some interesting outputs if you write something like
double x = 1/2. You might expect 0.5 in this case, but it will often evaluate the integer value on the right first before assigning and converting the result into a double, giving the value 0.0
It is important to note that when doing this kind of type conversion, it will never round the result. So if you do the opposite:
long x = (long)(1.0/2.0);
then while (1.0/2.0) will evaluate to 0.5, the (long) cast will force this to be truncated to 0. Even if I had long x = (long)(0.9), the result will still be 0. It simply truncates after the decimal point.
它无法舍入,因为它永远不会处于要舍入的状态
表达式“1/2”在分配给 long
之前永远不会是 0.5 现在,long x = 1.0/2.0
因为表达式赋值之前的右边对于舍入有效。除非你得到 0.499999999999997...It can't round because it's never in a state to be rounded
The expression "1/2" is never 0.5 before assign to long
Now,long x = 1.0/2.0
because the expression on the right before assign is valid for rounding. Unless you get 0.499999999999997...这个问题之前已经在这个网站上回答过,你正在进行整数除法,如果你想得到 0.5 使用:
你将得到
0.5
的值。this question was answered before on this site, you are doing an integer division, if you want to get the 0.5 use:
and you will get the value of
0.5
.有许多不同的舍入约定,最常见的是向 +inf 舍入、向 -inf 舍入和向零舍入。很多人认为有一种正确的方法,但他们对这种方法应该是什么有不同的想法;-)
整数除法没有中间的非整数结果,但当然除法是确定性地完成的,并且有一个特定的舍入对于特定平台和编译器,始终遵循约定。
使用 Visual C++,我得到 5/2 = 2 和 -5/2 = -2,四舍五入为零。
C、C++ 和 Java 中的舍入通常称为“截断”,意思是丢弃不需要的位。但这可能会产生误导。使用 4 位 2 的补码二进制,执行截断所暗示的操作...
这是向 -无穷大舍入,这就是 Python 所做的(或至少在 Python 2.5 中所做的)。
如果我们使用符号大小表示,截断将是正确的词,但几十年来,二进制补码一直是事实上的标准。
在 C 和 C++ 中,我期望虽然它通常被称为截断,但实际上这个细节在标准中未定义并留给实现 - 这是允许编译器使用平台最简单、最快的方法的借口(处理器除法指令是什么)自然是这样)。不过,如果你有负数,这只是一个问题 - 我还没有看到任何语言或实现可以给出 5/2 = 3。
我不知道 Java 标准是怎么说的。 Python 手册指定了“floor”除法,这是舍入到无穷大的常用术语。
编辑
额外注释 - 根据定义,如果 a/b = c 余数 d,则 a = (b*c)+d。为了保持这一点,您必须选择适合您的舍入约定的余数。
人们倾向于假设余数和模数相同,但 WRT 有符号值,它们可能不同 - 取决于舍入规则。根据定义,模值永远不会为负,但余数可以为负。
我怀疑 Python 向负无穷大舍入的规则旨在确保单个 % 运算符作为余数和模数都有效。在 C 和 C++ 中,% 的含义(余数或模数)是(是的,你猜对了)定义的实现。
Ada 实际上有两个独立的运算符 - mod 和 rem。除法需要向零舍入,因此 mod 和 rem 会给出不同的结果。
There are lots of different rounding conventions, the most common being rounding towards +inf, rounding towards -inf and rounding towards zero. Lots of people assume there's one right way, but they all have different ideas about what that one way should be ;-)
There is no intermediate non-integer result for integer division, but of course the division is done deterministically, and one particular rounding convention will always be followed for a particular platform and compiler.
With Visual C++ I get 5/2 = 2 and -5/2 = -2, rounding towards zero.
The rounding in C, C++ and Java is commonly called "truncation" - meaning drop off the unwanted bits. But this can be misleading. Using 4 bit 2s complement binary, doing what truncation implies gives...
Which is rounding towards -infinity, which is what Python does (or at least what it did in Python 2.5).
Truncation would be the right word if we used a sign-magnitude representation, but twos complement has been the de-facto standard for decades.
In C and C++, I expect while it's normally called truncation, in reality this detail is undefined in the standards and left to the implementation - an excuse for allowing the compiler to use the simplest and fastest method for the platform (what the processors division instruction naturally does). It's only an issue if you have negative numbers though - I've yet to see any language or implementation that would give 5/2 = 3.
I don't know what the Java standard says. The Python manual specifies "floor" division, which is a common term for rounding to -infinity.
EDIT
An extra note - by definition, if a/b = c remainder d, then a = (b*c)+d. For this to hold, you have to choose a remainder to suite your rounding convention.
People tend to assume that remainders and modulos are the same, but WRT signed values, they can be different - depending on the rounding rules. Modulo values are by definition never negative, but remainders can be negative.
I suspect the Python round-towards-negative-infinity rule is intended to ensure that the single % operator is valid both as a remainder and as a modulo. In C and C++, what % means (remainder or modulo) is (yes, you guessed it) implementation defined.
Ada actually has two separate operators - mod and rem. With division required to round towards zero, so that mod and rem do give different results.