Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 |

 

  Вопрос: Про математику... 0,5 - 0,4 не равно 0,1 ??? Добавлено: 11.06.11 21:50  

Автор вопроса:  DimBi
Как правильно выполнять математические вычисления?
У меня получается, что:
0,5 - 0,4 = 0,099999999999999978
проверял кодом:
Dim x As Double = 0.5
        Dim y As Double = 0.4
        Dim z As Double
        z = x - y
        If z = 0.1 Then
            Lbresult.Text = "равно"
        Else
            Lbresult.Text = "Не равно"
        End If


Почему так получается? Что надо сделать?

Ответить

  Ответы Всего ответов: 18  

Номер ответа: 1
Автор ответа:
 AWP



ICQ: 345685652 

Вопросов: 96
Ответов: 1212
 Web-сайт: xawp.narod.ru
 Профиль | | #1
Добавлено: 11.06.11 22:22
самое простое. Сделай ";Dim z As Single"

Ответить

Номер ответа: 2
Автор ответа:
 DimBi



Вопросов: 15
Ответов: 55
 Профиль | | #2 Добавлено: 11.06.11 22:33
к сожалению
  1. Dim z As Single
не работает!

Решил так:
  1. z = Math.Round(x - y, 2)

(количество знаков после запятой на результат не влияет, просто округляет 0,09999.... к 0,1)
но, хотелось бы понять, почему так происходит?

Ответить

Номер ответа: 3
Автор ответа:
 FedX



ICQ: 578776900 

Вопросов: 4
Ответов: 10
 Профиль | | #3 Добавлено: 11.06.11 22:46
А можно еще вот так:
  1. Private Sub Form_Load()
  2.     Dim x As Double
  3.     Dim y As Double
  4.     Dim z As Single
  5.     x = 0.5
  6.     y = 0.4
  7.     z = x - y
  8.     If z = 0.1 Then
  9.         Lbresult.Text = "Равно"
  10.     Else
  11.         Lbresult.Text = "Не равно"
  12.     End If
  13. End Sub

Ответить

Номер ответа: 4
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #4 Добавлено: 11.06.11 22:52
хотелось бы понять, почему так происходит?

Корень проблемы в стандарте IEEE-754, определяющем формат чисел с плавающей точкой.
Типы Double и Single его придерживаются и получают за это, что причитается.

Ответить

Номер ответа: 5
Автор ответа:
 DimBi



Вопросов: 15
Ответов: 55
 Профиль | | #5 Добавлено: 11.06.11 23:32
 И так не получится....

Ответить

Номер ответа: 6
Автор ответа:
 DimBi



Вопросов: 15
Ответов: 55
 Профиль | | #6 Добавлено: 11.06.11 23:36
Корень проблемы в стандарте IEEE-754

как же решается проблема?
Неужели пересчитывать каждое действие на этапе разработки?!
Может, какие правила есть?

Ответить

Номер ответа: 7
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #7 Добавлено: 11.06.11 23:41
Ну почему же, ты сам ведь понял, что нужно правильное округление и контроль значимых разрядов

Ответить

Номер ответа: 8
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #8 Добавлено: 11.06.11 23:50
Кроме того, есть тип Decimal.

Ответить

Номер ответа: 9
Автор ответа:
 DimBi



Вопросов: 15
Ответов: 55
 Профиль | | #9 Добавлено: 11.06.11 23:58
Вот что нашел про этот стандарт:
Стандарт IEEE 754 широко применяется в технике и программировании. При этом хочется отметить, что в нем заложены существенные недостатки. Создается впечатление, что в разработке стандарта не принимали участие профессиональные математики. Директор института математики и ее применений в Миннеаполисе, США Дуглас Н.Арнольд утверждает, что целый ряд крупнейших аварий с человеческими жертвами и миллиардными убытками всецело обязан нынешней технологии компьютерных вычислений и представлений данных по стандарту IEEE 754.


всю статью можно почитать здесь: http://www.vbstreets.ru/VB/Articles/66541.aspx

Ответить

Номер ответа: 10
Автор ответа:
 AWP



ICQ: 345685652 

Вопросов: 96
Ответов: 1212
 Web-сайт: xawp.narod.ru
 Профиль | | #10
Добавлено: 12.06.11 01:00
Стоить отметить, что в VB6 числа с плавающей точкой вычисляются нормально.

Ответить

Номер ответа: 11
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #11 Добавлено: 12.06.11 01:24
Ну, достаточно ведь одного примера, чтобы опровергнуть.
  1. Dim a  As Single
  2. Dim b  As Single
  3. Dim c  As Single
  4.     a = 0.5
  5.     b = 0.4
  6.     c = b - a

Ответить

Номер ответа: 12
Автор ответа:
 AWP



ICQ: 345685652 

Вопросов: 96
Ответов: 1212
 Web-сайт: xawp.narod.ru
 Профиль | | #12
Добавлено: 12.06.11 03:20
Да, одного хватает...
  1. Dim a  As Double
  2. Dim b  As Double
  3. Dim c  As Double
  4.     a = 0.5
  5.     b = 0.4
  6.     c = b - a

Ответить

Номер ответа: 13
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #13 Добавлено: 12.06.11 03:42
Не ты ли говорил :
самое простое. Сделай dim z As Single"

А теперь решил раздвинуть границы?
Есть такое понятие "фальсифициуемая теория". Можешь приводить сотню подтверждений, но достаточно одного опровержения.
Мне время тратить или сам поищешь?

Ответить

Номер ответа: 14
Автор ответа:
 Ким Чен Ир



Вопросов: 0
Ответов: 140
 Профиль | | #14 Добавлено: 12.06.11 05:23
|A|W|P| обиделся наверно. Извини.:)
  1.  
  2. 'vb6
  3. Dim a  As Double
  4. Dim b  As Double
  5. Dim c  As Double
  6.     a = 100000000.04
  7.     b = 100000000.05
  8.     c = b - a


Хоть числа представленные операндами a и b условно "большие", они и рядом не стоят с предельно допустимыми для double +/–1.7E308.
А результат тем более ...
И это просто вычитание. А что будет при умножении/делении, да с итерациями...

Ответить

Номер ответа: 15
Автор ответа:
 DimBi



Вопросов: 15
Ответов: 55
 Профиль | | #15 Добавлено: 12.06.11 10:46
вчера сервер перестал отвечать....

теперь видимо без костылей никак:
  1. Dim a As Double
  2.         Dim b As Double
  3.         Dim c As Double
  4.         a = 100000000.04
  5.         b = 100000000.05
  6.         c = Math.Round(b - a, 4, MidpointRounding.AwayFromZero)
  7.         LbTest.Text = c.ToString


или, если Decimal:
  1. Dim a As Decimal
  2.         Dim b As Decimal
  3.         Dim c As Decimal
  4.         a = CDec(100000000.04)
  5.         b = CDec(100000000.05)
  6.         c = b - a
  7.         LbTest.Text = c.ToString

Ответить

Страница: 1 | 2 |

Поиск по форуму





© Copyright 2002-2011 VBNet.RU | Пишите нам