если у меня есть что-то вроде:
long x = 1/2;
не следует ли округлять это значение до 1? Когда я печатаю это на экране, он говорит 0.
если у меня есть что-то вроде:
long x = 1/2;
не следует ли округлять это значение до 1? Когда я печатаю это на экране, он говорит 0.
Он выполняет целочисленное деление, которое обрезает все, что находится справа от десятичной точки.
(a / b) * b + a % b == a
и заверяет, что если a и b оба положительны, a / b
и a % b
будут неотрицательными. Если a и / или b отрицательны, знаки определяются реализацией (Стандарт, 5.6). У меня нет под рукой стандартных документов C или Java.
- person David Thornley; 03.02.2010
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded.
(то есть, это является усечением, но усечение определяется относительно числового значения, а не базового представления).
- person caf; 03.02.2010
Целочисленное деление уходит корнями в теорию чисел. Когда вы делаете 1/2, вы спрашиваете, сколько раз 2 равно 1? Ответ - никогда, поэтому уравнение принимает вид 0 * 2 + 1 = 1, где 0 - это частное (то, что вы получаете от 1/2), а 1 - остаток (то, что вы получаете от 1% 2).
Правильно отметить, что% не является истинным модулем в математическом смысле, а всегда является остатком от деления. Есть разница, когда вы имеете дело с отрицательными целыми числами.
Надеюсь, это поможет.
Это выражение сначала объявляет о существовании long с именем x, а затем присваивает ему значение выражения в правой части. Выражение в правой части - 1/2, а поскольку 1 и 2 являются целыми числами, это интерпретируется как целочисленное деление. При целочисленном делении результатом всегда является целое число, поэтому что-то вроде 5/3 вернет 1, так как только одна тройка подходит к пятерке. Итак, с 1/2, сколько двоек может поместиться в 1? 0.
В некоторых языках это может привести к интересным результатам, если вы напишете что-то вроде double x = 1/2. В этом случае вы можете ожидать 0,5, но он часто сначала оценивает целочисленное значение справа, прежде чем присваивать и преобразовывать результат в двойной, давая значение 0,0
Важно отметить, что при выполнении такого преобразования типа результат никогда не округляется. Итак, если вы сделаете наоборот: long x = (long) (1.0 / 2.0); тогда, в то время как (1.0 / 2.0) будет оцениваться как 0.5, (длинное) приведение приведет к усечению этого значения до 0. Даже если у меня было long x = (long) (0.9), результат все равно будет 0. Он просто усекает после десятичной точки.
Он не может округляться, потому что он никогда не может быть округлен
Выражение "1/2" никогда не было 0,5 до присвоения long
Теперь long x = 1.0/2.0
, потому что выражение справа перед assign допустимо для округления. Если вы не получите 0,499999999999997 ...
long x = 1.0 / 2.0 + 0.5
. Я полагаю, даже это не поможет, если в результате вы получите 0,499999999999997 ... (что меня очень удивит в данном случае), но если это так, вероятно, ничего не помогает, кроме не округление чисел с плавающей запятой до целых чисел.
- person UncleBens; 02.02.2010
(1.0 / 6.0) * 3.0 + 0.5
использует числа, которые нельзя точно представить в двоичном формате, и тогда я не удивлюсь неточным ответом.
- person David Thornley; 03.02.2010
на этот вопрос уже был дан ответ на этом сайте, вы выполняете целочисленное деление, если хотите использовать 0,5:
double x = (double)1/2;
и вы получите значение 0.5
.
Существует множество различных соглашений об округлении, наиболее распространенными из которых являются округление в сторону + inf, округление в сторону -inf и округление в сторону нуля. Многие люди предполагают, что есть один правильный путь, но все они имеют разные представления о том, каким должен быть этот путь ;-)
Для целочисленного деления нет промежуточных нецелочисленных результатов, но, конечно, деление выполняется детерминированно, и всегда будет соблюдаться одно конкретное соглашение об округлении для конкретной платформы и компилятора.
С Visual C ++ я получаю 5/2 = 2 и -5/2 = -2, округляя до нуля.
Округление в C, C ++ и Java обычно называется «усечением», что означает отбрасывание ненужных битов. Но это может вводить в заблуждение. Используя 4-битное двоичное дополнение до 2, выполнение того, что подразумевает усечение, дает ...
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 указано деление по полу, что является общим термином для округления до бесконечности.
ИЗМЕНИТЬ
Дополнительное примечание - по определению, если a / b = c остаток d, то a = (b * c) + d. Чтобы это сохранилось, вы должны выбрать остаток в соответствии с вашим соглашением об округлении.
Люди склонны предполагать, что остатки и модули одинаковы, но значения со знаком WRT могут быть разными - в зависимости от правил округления. Значения по модулю по определению никогда не бывают отрицательными, но остатки могут быть отрицательными.
Я подозреваю, что правило Python округления к отрицательной бесконечности предназначено для гарантии того, что единственный оператор% действителен как в качестве остатка, так и по модулю. В C и C ++ то, что означает% (остаток или по модулю), определяется (да, как вы уже догадались) реализацией.
На самом деле в Ada есть два отдельных оператора - mod и rem. При делении требуется округление до нуля, поэтому mod и rem do дают разные результаты.
a % b
было неотрицательным, поэтому 5 / 3
не могло быть 3, так как тогда 5 % 3
должно было бы быть -4. Он рекомендует округлять частное до нуля с отрицательными числами, но это определяется реализацией.
- person David Thornley; 03.02.2010