Баг или фича?
От: Vlad007 Россия  
Дата: 18.09.09 03:31
Оценка:
В результате выполнения следующих методов (C# 2008):
Console.WriteLine(Math.Round(1.4999999999999999));
Console.WriteLine(Math.Round(1.49));
получил два разных результата — 2 и 1.
Первый, естественно, неверен.
Понятно почему так получается — из-за неточности представления числа
в бинарном виде.
Но, с другой стороны, как ни крути — это ошибка!
Или, всё-таки, фича?...
Re: Баг или фича?
От: Camarada Россия  
Дата: 18.09.09 04:44
Оценка:
Здравствуйте, Vlad007, Вы писали:

V>В результате выполнения следующих методов (C# 2008):

V> Console.WriteLine(Math.Round(1.4999999999999999));
V> Console.WriteLine(Math.Round(1.49));
V>получил два разных результата — 2 и 1.
V>Первый, естественно, неверен.
V>Понятно почему так получается — из-за неточности представления числа
V>в бинарном виде.
V>Но, с другой стороны, как ни крути — это ошибка!
V>Или, всё-таки, фича?...

А вы заведите переменную типа double со значением 1.4999999999999999 и выведите ее на экран или отладчиком посмотрите.
Это не баг и не фича, это голая правда представления чисел с плавающей точкой.
Re[2]: Баг или фича?
От: Vlad007 Россия  
Дата: 18.09.09 06:38
Оценка:
Здравствуйте, Camarada, Вы писали:

C>А вы заведите переменную типа double со значением 1.4999999999999999 и выведите ее на экран или отладчиком посмотрите.

C>Это не баг и не фича, это голая правда представления чисел с плавающей точкой.

Да я понимаю, что происходит за ширмой: строка "1.4999999999999999"
из моей программы при компиляции преобразуется в double,
получается значение чуть большее 1.5 и в результате —
совсем неверный ответ 2.
И ошибка заключается именно в том, что неявное преобразование к типу double
в данном случае недопустимо, оно приводит к существенной ошибке!
Re[3]: Баг или фича?
От: Ziaw Россия  
Дата: 18.09.09 07:06
Оценка:
Здравствуйте, Vlad007, Вы писали:

V>И ошибка заключается именно в том, что неявное преобразование к типу double

V>в данном случае недопустимо, оно приводит к существенной ошибке!

Тут нет неявного преобразования. Что значит строка к типу? Конкретно это число в double так и выглядит, его по другому не предствишь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[3]: Баг или фича?
От: Camarada Россия  
Дата: 18.09.09 07:58
Оценка:
Здравствуйте, Vlad007, Вы писали:

V>Здравствуйте, Camarada, Вы писали:


C>>А вы заведите переменную типа double со значением 1.4999999999999999 и выведите ее на экран или отладчиком посмотрите.

C>>Это не баг и не фича, это голая правда представления чисел с плавающей точкой.

V>Да я понимаю, что происходит за ширмой: строка "1.4999999999999999"

V>из моей программы при компиляции преобразуется в double,
V>получается значение чуть большее 1.5 и в результате —
V>совсем неверный ответ 2.
V>И ошибка заключается именно в том, что неявное преобразование к типу double
V>в данном случае недопустимо, оно приводит к существенной ошибке!


Странное у вас представление. По умолчанию число в формате x.x — System.Double.
Как вы представляете компилятор должен догадаться, что вы хотите передать в метод. Он же должен сохранить это число на стеке и прочее.
Для точных расчетов в .NET есть тип Decimal (забыл написать), почитайте статью об этом типе в MSDN.
Re[4]: Баг или фича?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.09.09 08:15
Оценка:
Здравствуйте, Camarada, Вы писали:

C>Для точных расчетов в .NET есть тип Decimal (забыл написать), почитайте статью об этом типе в MSDN.


Decimal не спасает от проблем с многократным округлением:

using System;

class A
{
    static void Main()
    {
        var x = 1E-28M;
        Console.WriteLine(0 == x * 0.5M); // True
        Console.WriteLine(0 == x * 0.50000000000000000000000000005M); // True
        Console.WriteLine(0 == x * 0.50000000000000000000000000005000000000000000000001M); // False
    }
}
Re[5]: Баг или фича?
От: Camarada Россия  
Дата: 21.09.09 06:33
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, Camarada, Вы писали:


C>>Для точных расчетов в .NET есть тип Decimal (забыл написать), почитайте статью об этом типе в MSDN.


N>Decimal не спасает от проблем с многократным округлением:


Я не утверждал, но все же это не double.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.