2017-02-22 68 views
3

Я реорганизую ряд наших проектов для повторного использования с одним из наших клиентов, и я надеюсь на здравомыслие, чтобы проверить решение переписать один из разработчиков свойств.Является ли условие в этом наборе свойств действительным?

Я видел эту реализацию несколько раз в нашей кодовой базе, но, поскольку она была написана разработчиком, который больше не работает здесь, я не могу спросить его об этом.

Это происходит следующим образом:

private double _myProperty; 

public double MyProperty 
{ 
    get { return _myProperty; } 
    set 
    { 
     if (!(Math.Abs(_myProperty - value) < double.Epsilon)) 
     { 
      _myProperty = value; 
      OnPropertyChanged(); 
     } 
    } 
} 

Я хорошо знаком с написанием следующий синтаксис для инкубационных свойств:

if (value != _myProperty) 

Но в первом примере выше я интересно, если я отсутствующий что нибудь. Я знаю, что расчет Math.Abs ​​дает мне разницу между «значением» и текущим значением «_myProperty», но почему сравнение с double.Epsilon? Согласно IntelliSense и MSDN, double.Epsilon «представляет наименьшее положительное двойное значение, которое больше нуля». Так что, конечно, сравнение может так же легко быть:

if (Math.Abs(_myProperty - value) > 0) 

был предыдущий разработчик просто быть излишне сложным, или мне не хватает какой-то маленький нюанс C# Я еще не покрыты?

ответ

1

Коэффициенты - это то, что они означает, чтобы сделать это, чтобы использовать значение Эпсилона, отличное от double.Epsilon. Как вы отметили, double.Epsilon - это наименьшее значение, которое может представлять double, а два разных двойника могут быть ближе, чем double.Epsilon, и, как результат, их код функционально идентичен, просто проверяет, равна ли разница нулю, что является функциональным идентично просто выполнению регулярной проверки равенства двух удвоений.

Общая идея логики состоит в том, чтобы иметь числа, «близкие» друг к другу, чтобы считаться равными, где «достаточно близко» - это значение, основанное на значительных цифрах чисел, которые вы имеющий дело с. Либо они намеревались использовать SomeBusinessObject.Epsilon, который представляет точность значений, с которыми вы работаете, или просто пишете код культа и не понимаете, что они делают.

+0

Спасибо, я обновлю его, чтобы использовать более подходящее значение для Epsilon – Dmihawk

2

Сравнение равенства двух двойных значений с использованием Epsilon, безусловно, более корректно, но в большинстве случаев оно является излишним и может быть легко ошибочно закодировано по мере того, как докажет ваш пример.

разница между двумя удвоениями никогда не может быть меньше, чем Epsilon, но не равна нулю, как вы указываете. Чтобы быть эффективным (например, делать что-то более значимое, чем простой тест равенства), разница должна быть < = Epsilon.

if (!(Math.Abs(_myProperty - value) <= double.Epsilon)) 

Это позволяет использовать 1-битное колебание в двух значениях. Я думаю, вы сжигаете больше циклов процессора, чем спасите их. Конечно, для принятия пользовательской записи этот тест является полным излишним.

То, что я делал в прошлом, это определение моего собственного Эпсилона, имеющего смысл в реальном мире. Так, например, если я контролирую измерения температуры в реальном времени, меня не интересуют изменения менее, чем 1E-6 град F, и поэтому я буду определять Epsilon.