Значение этой константы является результатом деления положительного {или отрицательного} числа на ноль.

уйста, рассмотрите следующий код и комментарии:

Console.WriteLine(1 / 0); // will not compile, error: Division by constant zero

int i = 0;
Console.WriteLine(1 / i); // compiles, runs, throws: DivideByZeroException

double d = 0;
Console.WriteLine(1 / d); // compiles, runs, results in: Infinity   

Я могу понять, что компилятор активно проверяет деление на нулевую константу и DivideByZeroException во время выполнения, но:

Почему использование двойного числа в делении на ноль возвращает бесконечность, а не генерирует исключение? Это по замыслу или это ошибка?

Просто для удовольствия, я сделал это и в VB.NET, получив «более согласованные» результаты:

dim d as double = 0.0
Console.WriteLine(1 / d) ' compiles, runs, results in: Infinity

dim i as Integer = 0
Console.WriteLine(1 / i) '  compiles, runs, results in: Infinity

Console.WriteLine(1 / 0) ' compiles, runs, results in: Infinity

РЕДАКТИРОВАТЬ:

Основываясь на отзывах Кекекелы, я запустил следующее, что привело к бесконечности:

Console.WriteLine(1 / .0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001);

Этот тест, кажется, подтверждает идею и буквальный двойник0.0 на самом деле очень, очень маленькая фракция, которая приведет к бесконечности ...

 Jalal26 янв. 2014 г., 22:21
@EricLippert круто!
 Eric Lippert06 янв. 2011 г., 17:40
Вот моя статья на эту тему:blogs.msdn.com/b/ericlippert/archive/2009/10/15/...

Ответы на вопрос(5)

с плавающей точкой:

не ассоциативныне являются распределительнымиможет не иметь мультипликативного обратного

(видетьhttp://www.cs.uiuc.edu/class/fa07/cs498mjg/notes/floating-point.pdf для некоторых примеров)

Плавающая точка - это конструкция для решения конкретной проблемы, и она используется повсюду, когда этого не должно быть. Я думаю, что они довольно ужасны, но это субъективно.

Решение Вопроса

double Тип определяет значение для бесконечности, в то время какint типа нет. Так что вdouble В этом случае результатом вычисления является значение, которое вы можете фактически выразить в данном типе, поскольку оно определено. вint В этом случае нет значения бесконечности и, следовательно, нет способа вернуть точный результат. Отсюда и исключение.

VB.NET делает вещи немного по-другому; целочисленное деление автоматически приводит к значению с плавающей запятой, используя/ оператор. Это позволяет разработчикам писать, например, выражение1 / 2и оцените0.5, что некоторые считают интуитивно понятным. Если вы хотите увидеть поведение в соответствии с C #, попробуйте это:

Console.WriteLine(1 \ 0)

Обратите внимание на использованиецелочисленное деление оператор (\не/) выше. Я полагаю, вы получите исключение (или ошибку компиляции - не уверен, какой).

Точно так же попробуйте это:

Dim x As Object = 1 / 0
Console.WriteLine(x.GetType())

Приведенный выше код будет выводитьSystem.Double.

Что касается вопроса о неточности, вот другой способ взглянуть на это. Это не то, чтоdouble тип не имеет значения точно для нуля (он имеет); скорееdouble тип не предназначен для предоставленияматематически точные результаты на первом месте. (Некоторые значения могут быть представлены точно, да. Новычисления не дают никаких обещаний точности.) В конце концов, значениематематическая выражение1 / 0 не определено (последний раз я проверял). Но1 / x приближается к бесконечности, поскольку х приближается к нулю. Так что с этой точки зрения, если мы не можем представить большинство фракцийn / m именно так в любом случае, имеет смысл лечитьx / 0 случай как приблизительный и дать ему значениеподходы- снова, бесконечность определена, по крайней мере.

 AnorZaken22 сент. 2015 г., 21:24
Еще один пример того, как числа с плавающей точкой принципиально отличаются от действительных чисел, состоит в том, что числа с плавающей запятой определяют «-0.0» (отрицательный ноль), и если OP разделить на то, что результат будетNegative Infinity, Но что ты думаешь0.0 == -0.0 оценивает?
 AnorZaken22 сент. 2015 г., 21:16
Хотя этот ответ очень полезен, он также немного ошибочен. Ответ неправильный, потому что деление на ноль не является бесконечностью - оно математически не определено. Реальный ответ состоит в том, что двойные числа НЕ являются действительными числами (R), как указано в последней части этого ответа. Они являются числами с плавающей запятой, и OP пытается применить рассуждения действительных чисел к чему-то, что не является действительным числом. Они кажутся похожими в большинстве случаев, потому что они были разработаны, чтобы быть похожими, но они принципиально разные. Двойники определяют то, что называетсяNaN"Не число", (продолжает ...)
 AnorZaken22 сент. 2015 г., 21:17
(продолжение ...), который был бы более математически правильным «результатом», если бы это были фактически действительные числа. И все же он не вернул NaN. Причина примерно такая, как описано в ответе: потому что в логике с плавающей запятой вы в основном предполагаете, что «0.0» - это очень маленькое число. Однако нельзя сказать, что этоявляется небольшое число, заявив, что тамявляется и точное представление нуля вводит в заблуждение, потому что нет никакого преобразования 1-в-1 от числа с плавающей точкой к R. Скорее каждое значение с плавающей точкой отображается в диапазон действительных значений, и число с плавающей запятой "0.0" включает в себя обафактический нульа также ряд других небольших значений.

а не точное значение, поэтому то, на что вы на самом деле делите с точки зрения компилятора, что-то приближается к нулю, но не к нулю.

 slebetman06 янв. 2011 г., 00:17
На самом деле, double имеет представление значения, которое точно равно нулю. Реальная причина заключается в том, что по определению деление на ноль двойного приводит к значению Inf, то есть по замыслу не случайно.
 user987604 июл. 2013 г., 16:53
Компьютеры обычно не реализуют «нормальную» математику, как вас учили в школе, потому что это действительно сложно для компьютера. Вместо этого они обычно реализуют стандарт IEEE 754 с плавающей запятой, который похож, но имеет некоторые тонкие различия. Одно отличие состоит в том, что есть два нуля, +0 и -0, которые сравниваются равными. Они оба ноль. Наличие двух представлений нуля, очевидно, делает некоторые компьютерные алгоритмы быстрее / проще.
 slebetman07 янв. 2011 г., 00:07
@Jeffrey: +0 и -0 по-прежнему равны 0. Даже если вы утверждаете, что числа, меньшие, чем эпсилон, представлены как 0, вы все равно говорите, что слишком малые числа равны 0. Да, в математике -0 нет смысла но когда был разработан 754, физики, проводившие симуляции, утверждали, что они хотят знать, в каком направлении получен результат, если предел вычисления привел к 0.
 Jeffrey L Whitledge07 янв. 2011 г., 04:14
@slebetman - 1 / + 0 = + INF, но 1 / -0, с другой стороны, = -INF. Если они приводят к разным результатам в вычислениях, то как +0 и -0 оба могут быть равны нулю? Кроме того, +0 имеет такой же смысл, как и -0. Ноль это просто ноль. Это не имеет никакого знака вообще. Поведение чисел с плавающей запятой не имеет смысла, если только эти значения не рассматриваются как очень маленькие ненулевые значения. Но это имеет смысл, если это так считается.
 Jeffrey L Whitledge06 янв. 2011 г., 19:29
@slebetman - Если у двойников есть «представление значения, которое точно равно нулю», то почему двойники различают «+0» и «-0» и почему 1 / + 0 и 1 / -0 дают разные результаты? Идея «подписанного нуля» имеет смысл только в том случае, если эти значения рассматриваются как положительные или отрицательные значения, которые слишком малы для нормального представления. Обратите внимание, что в типах с плавающей точкой IEEE 754 нет нулевого знака.

это как-то связано с тем, что стандартные числа с плавающей запятой IEEE и числа с плавающей запятой двойной точности имеют заданное значение «бесконечность». .NET просто показывает то, что уже существует, на аппаратном уровне.

Посмотрите ответ Кекекела, почему это логично.

double тип соответствуетIEEE 754, стандарт для арифметики с плавающей точкой. Проверьте документацию дляDouble.NegativeInfinity а такжеDouble.PositiveInfinity.

Значение этой константы является результатом деления положительного {или отрицательного} числа на ноль.

Ваш ответ на вопрос