Доступ немного противоречив в том, как отменить событие.
Чтобы отменить подобные сообщения об ошибках, используйте DoCmd.CancelEvent
.
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 3162 then
MsgBox"ABC"
DoCmd.CancelEvent
End if
End sub
Я ожидал бы, что e1+e2 будет равняться e3+e4.
Это не совсем непохоже на ожидание
floor( 5/3 ) + floor( 2/3 + 1 )
равняться
floor( 5/3 + 2/3 ) + floor( 1 )
кроме Вы умножаетесь 2^53 перед получением слова.
Используя плавающую точку точности на 12 битов и усечение с Вашими значениями:
1.0 = 1.00000000000 1.1 = 1.00011001100 1.2 = 1.00110011001 1.0 + 1.1 = 10.00011001100 // extended during sum r1 = 1.0 + 1.1 = 10.0001100110 // truncated to 12 bit r1 + 1.2 = 11.01001100101 // extended during sum r2 = r1 + 1.2 = 11.0100110010 // truncated to 12 bit 1.1 + 1.2 = 10.01001100110 // extended during sum r3 = 1.1 + 1.2 = 10.0100110011 // truncated to 12 bit r3 + 1.0 = 11.01001100110 // extended during sum r4 = r3 + 1.0 = 11.0100110011 // truncated to 12 bit
Так изменение порядка операций/усечений вызывает ошибку измениться, и r4! = r2. Если Вы добавляете 1.1 и 1.2 в этой системе, последний бит несет, таким образом, в не потерянный на усечении. Если Вы добавляете 1.0 к 1,1, последний бит 1,1 потерян и таким образом, результатом не является то же.
В одном упорядочивании округление (усечением) удаляет запаздывание 1
.
В другом упорядочивании округление удаляет запаздывание 0
оба раза.
Каждый не равняется нулю; таким образом, ошибки не являются тем же.
Удваивается имеют намного больше битов точности, и C#, вероятно, использует округление, а не усечение, но надо надеяться эта простая модель показывает Вам, различные ошибки могут произойти с различными упорядочиваниями тех же значений.
Различие между fp и математикой - то, что + сокращение от того, 'добавьте затем вокруг' вместо того, чтобы просто добавить.
c# компилятор ничего не делает. ЦП.
если Вы имеете в регистре ЦП, и Вы затем добавляете B, результатом, сохраненным в том регистре, является A+B, приближенный к плавающей используемой точности
Если Вы затем добавляете C, ошибка складывает. Это ошибочное дополнение не является переходной операцией, таким образом заключительное различие.
Посмотрите классическую бумагу (Что каждый программист должен знать об арифметике с плавающей точкой) на предмете. Этот вид материала - то, что происходит с арифметикой с плавающей точкой. Это берет программиста, чтобы сказать Вам, что 1/3+1/3+1/3 is'nt равняются 1...
Порядок операций с плавающей точкой важен. Непосредственно не отвечает на Ваш вопрос, но необходимо всегда быть осторожными числами с плавающей точкой сравнения. Обычно включать допуск:
double epsilon = 0.0000001;
if (abs(result1 - result2) <= epsilon)
{
...
}
Это может представлять интерес: Что Каждый Программист Должен Знать Об Арифметике С плавающей точкой
result1 должен всегда равняться result2 праву?
Неправильно. Это правда в математике, но не в арифметике с плавающей точкой.
Необходимо будет прочитать некоторую Числовую Аналитическую краткую информацию.
То, почему ошибки не являются тем же в зависимости от порядка, может быть объяснено с другим примером.
Скажем, это для чисел ниже 10, это может сохранить все числа, таким образом, это может сохранить 1, 2, 3, и так далее до и включая 10, но после 10, это может только сохранить каждое второе число, из-за внутренней потери точности, другими словами, это может только сохранить 10, 12, 14, и т.д.
Теперь, с тем примером, Вы будете видеть, почему следующее приводит к различным результатам:
1 + 1 + 1 + 10 = 12 (or 14, depending on rounding)
10 + 1 + 1 + 1 = 10
Проблема с числами с плавающей точкой состоит в том, что они не могут быть представлены точно, и ошибка не всегда идет тем же путем, таким образом, порядок будет иметь значение.
Например, 3.00000000003 + 3.00000000003 мог бы закончить тем, что был 6.00000000005 (заметьте не 6 в конце), но 3.00000000003 + 2.99999999997 мог бы закончить тем, что был 6.00000000001, и с этим:
step 1: 3.00000000003 + 3.00000000003 = 6.00000000005
step 2: 6.00000000005 + 2.99999999997 = 9.00000000002
но, измените порядок:
step 1: 3.00000000003 + 2.99999999997 = 6.00000000001
step 2: 6.00000000001 + 3.00000000003 = 9.00000000004
Таким образом, это будет иметь значение.
Теперь, конечно, Вы могли бы быть удачливыми в этом, вышеупомянутые примеры балансируют друг друга, в котором первое будет качаться .xxx1 и другим вниз .xxx1, давая Вам .xxx3 в обоих, но нет никакой гарантии.
Вы на самом деле не используете те же значения, потому что промежуточные результаты отличаются:
double result1 = 2.1 + 1.2;
double result2 = 2.2 + 1.1;
Поскольку удваивается, не может представить десятичные значения точно, Вы получаете различные результаты.