Гость
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / VBA, вычитание с неправильным результутом (ms access) / 10 сообщений из 10, страница 1 из 1
17.02.2015, 15:48
    #38881921
SAURONoff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
Доброго времени суток.
Столкнулся я в своей базе (access) с проблемой при работе с дробными числами (чертовы копейки) - два одинаковых числа при сравнении оказывались разными. В оригинале это выглядит как "If (rst2!cert_sum / rst2!cert_days) * rst1!days <> rst1!sum Then".
Упростив пример, и откинув взаимодействие с таблицами, дабы отсечь возможные причины, пришел к следующему:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
                    Dim temp3 As Single 'явно объявим все переменные
                    Dim temp4 As Single
                    Dim temp5 As Single
                    Dim temp6 As Single
                    Dim temp7 As Single
                    temp3 = 1861.2 ' присвоил число
                    temp6 = 1861.2 ' присвоил второе число
                    temp7 = (temp6) - (temp3) 'простое вычитание
                    MsgBox temp6 & " __ " & temp3 & " __ " & temp7 'покажем через пробелы оба числа и получившееся значение


В таком виде получаем на выходе "1861,2 __ 1861,2 __ 0". Всё верно. Меняем исходные, теперь temp6 вычислим.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
                    Dim ~'те же объявления
                    temp3 = 1861.2
                    temp4 = 3 
                    temp5 = 620.4 
                    temp6 = temp4 * temp5 'Всё то же самое, только теперь 1861.2 получено умножением, а не сразу.
                    temp7 = (temp6) - (temp3)
                    MsgBox temp6 & " __ " & temp3 & " __ " & temp7


И на выходе... "1861,2 __ 1861,2 __ 1,220703E-04". А надо 0.

Честно пытался нагуглить, не вышло.
И со второй странностью столкнулся. Тот же (второй) код, но объявление заменил на "Dim temp3, temp4, temp5, temp6, temp7 As Single". Ничего ведь не должно было измениться, да? Однако, на выходе стал получать "1861,2 __ 1861,2 __ 2,273737E-13"
...
Рейтинг: 0 / 0
17.02.2015, 16:01
    #38881948
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
SAURONoffТот же (второй) код, но объявление заменил на "Dim temp3, temp4, temp5, temp6, temp7 As Single". Ничего ведь не должно было измениться, да?должно, это разные определения, читаем справку по Dim

SAURONoffдва одинаковых числа при сравнении оказывались разнымичисла с правающей точкой неточные по определению. Корректно сравнивать их с допустимой точностью, например вместо
Код: vbnet
1.
If a = b Then

надо
Код: vbnet
1.
If Abs(a - b)< 0.0001 Then


Второй вариант - использовать округления.
В любом случае ноль в Single и Double не равны целому нулю.

Учим матчасть по числам с плавающей точкой (запятой)
...
Рейтинг: 0 / 0
17.02.2015, 16:03
    #38881950
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
SAURONoffс дробными числами (чертовы копейки )не надо вообще использовать Single для денежных величин. Деньги точность любят
...
Рейтинг: 0 / 0
17.02.2015, 16:06
    #38881959
Currency
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
SAURONoff,

автор два одинаковых числа при сравнении оказывались разными
Single (как и Double) - это "не точные" (approximate) типы данных
Нужно использовать Currency
авторТот же (второй) код, но объявление заменил на "Dim temp3, temp4, temp5, temp6, temp7 As Single". Ничего ведь не должно было измениться, да?
Нет. Теперь переменные temp3, temp4, temp5, temp6 объявленны с типом Variant , а не Single
...
Рейтинг: 0 / 0
17.02.2015, 16:14
    #38881979
SAURONoff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
CurrencyНужно использовать Currency
---
Нет. Теперь переменные temp3, temp4, temp5, temp6 объявленны с типом Variant , а не Single

Но... MSDN...
https://msdn.microsoft.com/ru-ru/library/7ee5a7s1.aspx
"Объявление нескольких переменных"
Код: vbnet
1.
2.
Dim a, b, c As Single, x, y As Double, i As Integer
' a, b, and c are all Single; x and y are both Double



И https://msdn.microsoft.com/ru-ru/library/47zceaw7.aspx - никакого Currency...

Впрочем, поменял на Currency - вроде, работает...
...
Рейтинг: 0 / 0
17.02.2015, 16:21
    #38881995
SAURONoff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
Понятно. Visual Basic в Visual Studio и Visual Basic в офисе в некоторых вещах отличаются. В том числе, DIM работает по-разному.
Спасибо всем!
...
Рейтинг: 0 / 0
17.02.2015, 16:27
    #38882003
VBA, вычитание с неправильным результутом (ms access)
SAURONoff,

1) почитайте хоть какую-нибудь литературу (конспекты лекций) по форматам чисел с плавающей запятой (стандарт IEEE 754) и вычислительной математике;
2) не сравнивайте на равенство или не равенство числа с плавающей запятой;
2а) помните, что формат представления числа (человеку) - десятичный, в то время как хранения в большинстве случаев (машинный) - двоичный;
2б) на форуме есть ФАК по Access, см. Q19;
3) не используйте Single для хранения денежных сумм, и почитайте справку по диапазону значений и точности; используйте Currency или (Variant подтипа) Decimal ("Действительное" в конструкторе таблиц русской версии Access);

>"Dim temp3, temp4, temp5, temp6, temp7 As Single". Ничего ведь не должно было измениться, да?
Нет.справка по Dim StatementIf you don't specify a data type or object type, and there is no Deftype statement in the module, the variable is Variant by default.Ну, и TypeName() для проверки.

P. S. Не знаю, стоит ли поздравлять с этим, но список граблей просто образцово-показательный.
...
Рейтинг: 0 / 0
17.02.2015, 16:29
    #38882004
VBA, вычитание с неправильным результутом (ms access)
"нет, я не тормоз" :)
...
Рейтинг: 0 / 0
17.02.2015, 16:31
    #38882007
VBA, вычитание с неправильным результутом (ms access)
Shocker.ProВ любом случае ноль в Single и Double не равны целому нулю.Равны.
...
Рейтинг: 0 / 0
17.02.2015, 17:41
    #38882093
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBA, вычитание с неправильным результутом (ms access)
13-й кварталсписок граблей просто образцово-показательный.ты забыл еще одни классические граблиSAURONoffНо... MSDN...
https://msdn.microsoft.com/ru-ru/library/7ee5a7s1.aspx
"Объявление нескольких переменных"Автор не различает Visual Basic и VB.NET. Это два несовместимый языка и синтаксис у них разный. И вообще, зачем было лезть в MSDN, когда всего-то надо было нажать F1
SAURONoffVisual Basic в Visual Studio и Visual Basic в офисе в некоторых вещах отличаютсяVisual Basic в Visual Studio до 6.0 включительно (а также VBA в офисе) и Visual Basic .NET в Visual Studio .NET не просто в некоторых вещах отличаются, а это вообще разные языки)


13-й кварталShocker.ProВ любом случае ноль в Single и Double не равны целому нулю.Равны.я имел ввиду вычисленный, как в примере автора. "Чиcтый" ноль - таки да, равен ))
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / VBA, вычитание с неправильным результутом (ms access) / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]