Проблема с вычислениями
От: fightcat  
Дата: 26.12.06 03:16
Оценка:
Здравствуйте!
Только начал заниматься .NET и сразу столкнулся с проблемой:

Следующая программа


using System;
using System.Collections.Generic;
using System.Text;


namespace test1
{
    public class Class1
    {
        public static void Main(){
            double x1, x2, step;
            x1 = 1 ;
            x2 = 10;
            step = 0.1;

            while(x1<=x2) {
                x1 += step;
                Console.WriteLine("{0}", x1);
            }


            return;
        }
    }
}


выводит ожидаемые значения до 6,1, а потом начинает выдавать 6,1999999, 6,299999 и так далее.

Совершенно не понимаю, из-за чего это может происходить

Заранее спасибо за помощь
Re: Проблема с вычислениями
От: _d_m_  
Дата: 26.12.06 04:02
Оценка:
Здравствуйте, fightcat, Вы писали:

F>Здравствуйте!

F>Только начал заниматься .NET и сразу столкнулся с проблемой:

F>Следующая программа



F>
F>using System;
F>using System.Collections.Generic;
F>using System.Text;


F>namespace test1
F>{
F>    public class Class1
F>    {
F>        public static void Main(){
F>            double x1, x2, step;
F>            x1 = 1 ;
F>            x2 = 10;
F>            step = 0.1;

F>            while(x1<=x2) {
F>                x1 += step;
F>                Console.WriteLine("{0}", x1);
F>            }


F>            return;
F>        }
F>    }
F>}
F>


F>выводит ожидаемые значения до 6,1, а потом начинает выдавать 6,1999999, 6,299999 и так далее.


F>Совершенно не понимаю, из-за чего это может происходить


Проблема в том, что круглые числа в двоичной системе исчисления и в десятичной — разные. Это касается как мантиссы, так и экспоненты. Вот и приходится округлять компилятору до наиболее ближайшего подходящего числа твое 1*10^-1.
Re[2]: Проблема с вычислениями
От: fightcat  
Дата: 26.12.06 08:34
Оценка:
___>Проблема в том, что круглые числа в двоичной системе исчисления и в десятичной — разные. Это касается как мантиссы, так и экспоненты. Вот и приходится округлять компилятору до наиболее ближайшего подходящего числа твое 1*10^-1.

Спасибо. Просто никогда с подобным не сталкивался
А можно ли это как-то побороть? Очень хочется, чтобы 5,1 + 0,1 = 5,2
Re[3]: Проблема с вычислениями
От: Igore Россия  
Дата: 26.12.06 08:40
Оценка:
Здравствуйте, fightcat, Вы писали:

___>>Проблема в том, что круглые числа в двоичной системе исчисления и в десятичной — разные. Это касается как мантиссы, так и экспоненты. Вот и приходится округлять компилятору до наиболее ближайшего подходящего числа твое 1*10^-1.


F>Спасибо. Просто никогда с подобным не сталкивался

F>А можно ли это как-то побороть? Очень хочется, чтобы 5,1 + 0,1 = 5,2

1. Использовать тип decimal
2. Самому округлять, сравнить с учетом погрешности
Re[3]: Проблема с вычислениями
От: _d_m_  
Дата: 26.12.06 09:32
Оценка:
Здравствуйте, fightcat, Вы писали:

___>>Проблема в том, что круглые числа в двоичной системе исчисления и в десятичной — разные. Это касается как мантиссы, так и экспоненты. Вот и приходится округлять компилятору до наиболее ближайшего подходящего числа твое 1*10^-1.


F>Спасибо. Просто никогда с подобным не сталкивался

F>А можно ли это как-то побороть? Очень хочется, чтобы 5,1 + 0,1 = 5,2

Ну оно в принципе так и будет... Приблизительно... Просто вывод округляй:
Console.WriteLine("{0}", Math.Round(x1, 1));
Re: Проблема с вычислениями
От: fightcat  
Дата: 26.12.06 14:53
Оценка:
Тип decimal оказался тем что нужно.
Огромное всем спасибо.
Re[3]: Проблема с вычислениями
От: AK85 Беларусь  
Дата: 26.12.06 20:18
Оценка:
Здравствуйте, fightcat, Вы писали:

___>>Проблема в том, что круглые числа в двоичной системе исчисления и в десятичной — разные. Это касается как мантиссы, так и экспоненты. Вот и приходится округлять компилятору до наиболее ближайшего подходящего числа твое 1*10^-1.


F>Спасибо. Просто никогда с подобным не сталкивался

F>А можно ли это как-то побороть? Очень хочется, чтобы 5,1 + 0,1 = 5,2
С числами с плавающей точкой не получится, нужно определить "машинную дельту", стандартную погрешность машины при переводе из двоичной системы в десятичную (оч просто) а затем сравнивать разницу чисел с этой погрешностью.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.