Краткость.
существуют дополнительные льготы для обеспечения ясности между пространствами имен, которые совместно используют имена типов, но по существу это - просто сахар.
Это проблема с плавающей точностью.
Второй оператор работает, потому что компилятор считает выражение 1e-3 * 1e3 перед выдачей .exe.
Посмотрите его в ILDasm / Reflector, он выдаст что-то вроде
if (1.0 < 1.0)
Console.WriteLine("Wrong");
Проблема здесь довольно тонкая. Компилятор C # не (всегда) генерирует код, который выполняет вычисления с двойной точностью, даже если это тот тип, который вы указали. В частности, он генерирует код, который выполняет вычисления с «расширенной» точностью с использованием инструкций x87, без округления промежуточных результатов до удвоения.
В зависимости от того, оценивается ли 1e-3 как двойное или длинное двойное, и вычисляется ли умножение в double или long double можно получить любой из следующих трех результатов:
Очевидно, первое сравнение, тот, который не оправдывает ваши ожидания, оценивается в порядке, описанном в третьем сценарии, который я перечислил. 1e-3 округляется до удвоения либо потому, что вы сохраняете его и загружаете снова, что вызывает округление, либо потому, что C # распознает 1e-3 как литерал с двойной точностью и обрабатывает его таким образом. Умножение оценивается как long double, потому что C # имеет безумную числовую модель , именно так компилятор генерирует код.
Умножение во втором сравнении либо оценивается с использованием одного из два других метода (вы можете выяснить, какой из них, попробовав «1> 1e-3 * 1e3»), или компилятор округляет результат умножения, прежде чем сравнивать его с 1.0, когда он оценивает выражение во время компиляции.
Вероятно, вы можете указать компилятору не использовать расширенную точность без вашего указания через некоторые настройки сборки; включение генерации кода для SSE2 также может работать.
Ммм ... странно. Я не могу воспроизвести вашу проблему. Я также использую C # 3.5 и Visual Studio 2008. Я набрал в вашем примере точно , как он был опубликован, и я не вижу выполнения ни одного оператора Console.WriteLine
.
Кроме того, второй оператор if оптимизируется с помощью компилятор. Когда я исследую как отладочную, так и выпускную сборки в ILDASM / Reflector, я не вижу никаких свидетельств этого. Это происходит потому, что я получаю предупреждение компилятора о том, что на нем обнаружен недостижимый код.
Наконец, я не понимаю, как это могло быть проблемой точности с плавающей запятой. Почему компилятор C # статически оценивает два двойных значения иначе, чем CLR во время выполнения? Если бы это было действительно так, то можно было бы привести аргумент, что в компиляторе C # есть ошибка.
Изменить: Поразмыслив еще немного, я еще больше убедился, что это не проблема точности с плавающей запятой. Вы, должно быть, наткнулись на ошибку в компиляторе или отладчике, или опубликованный вами код не совсем соответствует вашему действительному запущенному коду. Я очень скептически отношусь к ошибке в компиляторе, но ошибка в отладчике кажется более вероятной. Попробуйте пересобрать проект и запустить его снова. Возможно, отладочная информация, скомпилированная вместе с exe, рассинхронизировалась или что-то в этом роде.
Я очень скептически отношусь к ошибке в компиляторе, но ошибка в отладчике кажется более вероятной. Попробуйте пересобрать проект и запустить его снова. Возможно, отладочная информация, скомпилированная вместе с exe, рассинхронизировалась или что-то в этом роде. Я очень скептически отношусь к ошибке в компиляторе, но ошибка в отладчике кажется более вероятной. Попробуйте пересобрать проект и запустить его снова. Возможно, отладочная информация, скомпилированная вместе с exe, рассинхронизировалась или что-то в этом роде.