Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.02.2013, 15:51   #1
blackarrow
Пользователь
 
Регистрация: 14.05.2011
Сообщений: 37
Злость сравнение результатов расчетов

Господа, прошу помощи. Есть стойкое ощущение, что меня где-то глубоко заклинило.
Есть ячейка (в приложенном файле В1), в которой находится рез-т простого расчета - значение А1*0,65, результат в В1 точно такой, каким он и должен быть. Затем, мы в коде умножаем значение А1 на 65/100, получаем отображаемый результат через debug.print точно соответствующий тому, что видим в В1.
А теперь сравниваем свой расчет и значение В1 и получаем ответ "не равно"?!
Формат данных в расчете - double, точно как использует сам Excel в формулах на листах, режим "точность как на экране" выключен.
Как это объяснить?
Вложения
Тип файла: zip test.zip (65.6 Кб, 10 просмотров)
blackarrow вне форума Ответить с цитированием
Старый 10.02.2013, 17:17   #2
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

Файл открыть не могу, но проблема известная: результат вычислений с плавающей точкой зависит от порядка операций. Т. е. для компьютерной арифметики не соблюдаются обычные правила типа a+b+c = c+b+a, a(b+c)=ab+ac и т.д.
Это связано с конечной точностью представления десятичных дробей в двоичном виде. Вот анализ вашей проблемы в окне Immediate:
Код:
?3*0.65, 3*65/100, 3*0.65=3*65/100,3*0.65-3*65/100
 1,95          1,95         False          6,657001339061E-17
Пути решения проблемы обсуждали недавно тут: http://www.cyberforum.ru/vba/thread776026.html
exceleved@yandex.ru Яндекс.Деньги: 410011500007619
Казанский вне форума Ответить с цитированием
Старый 10.02.2013, 17:49   #3
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Код:
If CStr(y) <> CStr(x) Then Debug.Print "WTF?"
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 10.02.2013, 18:21   #4
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

Игорь, а "WTF" - это что? "What The Fuck?"
гугль переводит "что за чертовщина?"

blackarrow, ситуация, в которой Вы оказались, по другому не обьяснить никак, разве что... внимательно присмотритесь к сообщению Казанского.
"Тщательнее надо..." (С) М.Жванецкий.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 10.02.2013, 18:28   #5
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Это вопрос к ТС
Я бы перевёл "Что за н***й?"
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 10.02.2013, 19:24   #6
blackarrow
Пользователь
 
Регистрация: 14.05.2011
Сообщений: 37
По умолчанию

Да, господа, спасибо. Хорошо быть профессионалом. WTF расшифровали правильно. Просто пока я понял, что что-то ломается и "собака порылась" именно на стыке 0,65 и 65/100 и следовательно, как надо сформулировать вопрос, было уже около 4-х часов утра
уже изучаю вот этот материальчик - http://support.microsoft.com/kb/78113
blackarrow вне форума Ответить с цитированием
Старый 12.02.2013, 23:14   #7
blackarrow
Пользователь
 
Регистрация: 14.05.2011
Сообщений: 37
По умолчанию

Продолжу, господа хорошие, рассказ о своих мытарствах. Может кому еще поможет. Почитав добрых людей, я быстренько взял if round(x,2) > round(y,2) then ... Все отлично, у меня все работает. Макрос, в недрах которого таким образом идут сравнения клиентских данных с эталонным расчетом, пущен в тестовую эксплуатацию уже будущим пользователям. И тут внезапно мне сообщают о том, что оказывается работает да все равно не всегда.

Разбирательство привело меня к интересному наблюдению поведения функции round, смотрите:
Код:
Dim d As Double: d = 1821.365
Dim c As Double: c = 1940.705
Debug.Print Round(d, 2)
Debug.Print Round(c, 2)
Получаем соответственно 1821,36 и 1940,7. Это что за округление такое?

А теперь делаем дьявольский ход:
Код:
Debug.Print Application.WorksheetFunction.Round(d, 2)
Debug.Print Application.WorksheetFunction.Round(c, 2)
на выходе: 1821,37 и 1940,71

Этому есть какое-то рациональное объяснение?

Последний раз редактировалось blackarrow; 12.02.2013 в 23:20.
blackarrow вне форума Ответить с цитированием
Старый 12.02.2013, 23:19   #8
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Цитата:
Этому есть какое-то рациональное объяснение?
есть)
Application.WorksheetFunction.Round - это функция листа Excel (формула)
Round - это функция VBA
Это 2 разные функции, потому и результаты отличаются

почитайте про округление здесь:
http://www.planetaexcel.ru/forum/ind...FID=8&TID=3483

Цитата:
функция Round() в VBA округляет не по математическим правилам, а по банковским

В частности:
Round(1.5)=2, ничего необычного;
Но Round(2.5)=2, а не 3, как обычно ожидается.

Упрощенно, для одного десятичного знака правило банковского округления такое: половинки (0.5), прибавленные к нечетным числам округляются до целых с избытком, а к четным - с недостатком.
Смысл - в уменьшении систематической ошибки округления при суммировании большого количества чисел.
EducatedFool вне форума Ответить с цитированием
Старый 12.02.2013, 23:29   #9
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

?Round(1.375, 2) - дает 1.38
есть такое понятие "бухгалтерское округление" - округляемая пятерочка округляет предыдущую цифру до парного значения.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 12.02.2013, 23:29   #10
blackarrow
Пользователь
 
Регистрация: 14.05.2011
Сообщений: 37
По умолчанию

Спасибо. Хотя бы в справке пару слов сказали по этому поводу...
Хотя вот здесь есть, нашел тоже - http://support.microsoft.com/kb/194983/en-us?fr=1
blackarrow вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сравнение двух множеств (результатов подзапросов) yaapelsinko SQL, базы данных 2 14.11.2012 12:58
ветвление графиков и расчетов SonicBob Общие вопросы Delphi 0 25.12.2011 12:16
Перенос расчетов из Excel в Delphi Himik Помощь студентам 1 29.10.2010 22:03
Таблица расчетов. Bilargo PHP 4 23.09.2010 18:13
Сохранение результата расчетов макроса Stanislav D Помощь студентам 1 15.08.2009 15:13