Ошибки в программе калькулятор
BachDoug Hoffman worked on the MASPAR (the Massively Parallel computer, 64K parallel processors).
The MASPAR has several built-in mathematical functions. The Integer square root function takes a 32-bit word as an input, interpreting it as . an integer (value is between 0 and 2 32 -1). There are 4,294,967,296 possible inputs to this function. How many should we test?What if you knew this machine was to be used for mission-critical and life-critical applications?
•To test the 32-bit integer square root function, Hoffman checked all values (all 4,294,967,296 of them). This took the computer about 6 minutes to run the tests and compare the results to an oracle. •There were 2 (two) errors, neither of them near any boundary. (The underlying error was that a bit was sometimes missed, but in most error cases, there was no effect on the final calculated result.) Without an exhaustive test, these errors probably wouldn‟t have shown up. •What about the 64-bit integer square root? How could we find the time to run all of these? If we don't run them all, don't we risk missing some bugs?Дайте пожалуйста ссылку на стандарт по которому вы "отрабатывали ситуации".
У меня есть идея, что вы бессистемно подергали окно и проверили пару тривиальных значений.
Делитесь, что проверяли, как именно, и с какой целью.
вы проверили, что получаемый вами ответ корректен? вы проверили все специфичные для функций значения?
Кейс предложенный bobylev мы рассматривать не будем, как излишне специфичный.
Является ли отсутствие ограничения на ввод,дефектом?
И является ли дефектом то что при полноэкранном режиме программа находится в левом верхнем углу??а все остальное пространство занимается белый фон?
1) да, критичность зависит от требований к системе.
2) нет не является. ну можно предположить, что у такого окна не должно быть полноэкранного режима, но это такой минорный минор.
Отвяжитесь от интерфейса, вы его уже проверили, у вас есть основная функциональность и вы про нее вообще ни слова не сказали.
Какие значения вы проверяли? почему? какой результат ожидали и получили?
Как вы вообще проверяли корректность log base высчитанного из одного параметра?
1. Что значит "все"? Список проверок есть? Пишите сюда. Если нет - составьте и напишите.Да.Все значения проверялись.Может я не замечаю какие не будь типичные дефекты.
Является ли отсутствие ограничения на ввод,дефектом?
И является ли дефектом то что при полноэкранном режиме программа находится в левом верхнем углу??а все остальное пространство занимается белый фон?
2. Что значит "отсутствие ограничений на ввод"? Можно пример, пожалуйста. Такие вещи обычно регулируются требованиями, но вы опять скажете, что их нет)
3. Является, но за такой баг в списке дефектов на первом месте хочется оторвать руки)
Пожалуйста, не надо отталкиваться от юзабилити!! Если требований нет, то их надо получить. Если вам их не дают, то надо составить свои и согласовать, что вот мол основа для тестовой модели. И заодно подумать так ли интересно работать там, где требования должны составлять тестировщики.Спасибо за внимание.
Так как отсутствует спецификация и какая либо документация.Отталкиваться приходиться от простого юзабилити.
Но только не надо приплетать сюда юзабилити и обсуждать дефекты максимизации окна до проверки математики. Вы даже тест на корень из отрицательного числа не упомянули еще)
Вас уже несколько раз попросили дать конкретику:
— Какие значения вы проверяли? почему? какой результат ожидали и получили?
— Что значит "все"? Список проверок есть? Пишите сюда. Если нет - составьте и напишите.
Вместо списка опять абстракция " Я пробовал с положительными числами". С КАКИМИ? Раз вы упорно игнорируете этот вопрос, видимо, это было 1-2 значения или просто бессистемное тыкание. Ну так то да, как вам и сказал руководитель, "этого мало"
Положительные числа от 0.1 до 10000.Граничными значениями.
Спасибо,но я уже разобрался.
Положительные числа от 0.1 до 10000.
Граничными значениями.
Спасибо,но я уже разобрался.
Если не затруднит, напишите, как разобрались, чтобы вопрос остался освещенным.
bobylev имхо прав, как минимум несколько миллионов значений надо прогнать через юнит тесты, как минимум ручной тестировщик может попросить девелоперов сделать это, вероятно ошибки могут быть на каких-то значениях. также сравнить эти миллионы результатов с результатами от другой библиотеки
обратить особое внимание на "потерю точности", например взять "самое маленькое поддерживаемое число" и посчитать значения, потом взять "второе самое маленькое" и тоже посчитать, ещё увеличить и посчитать. и так далее. исследовать результаты, верны ли они. так же можно сделать с максимальным числом, и где-то в середине
сколько знаков отображает результат? наверное не полное значение ведь оно может быть бесконечным? тогда наверное округляет последнее отображаемое значение? есть три разных округления плюс простая обрезка - какой вариант используется и правильный ли он?
а если в качестве десятичного разделителя использовать не "." а "," ?
при некоторых локализациях машины именно "," будет использоваться (меняем десятичный разделитель в настройках машины)
а как насчёт разделителя тысяч? в зависимости от локализации "." и "," могут использоваться. например 1.000.000,01 валидный вариант для некоторых локализаций, 1,000,001.01 для других
(меняем разделитель тысяч в настройках машины)
числа могут начинаться с нуля, например 001 и 001.01
могут заканчиваться "лишними" нулями, например 0.10, или иметь "лишнюю" десятичную часть, например 1.00 либо 1.00000000
какое самое маленькое число поддерживается? какое самое большое? поддерживается ли нотация записи через "е"?
как насчёт знака "+"? например "+0.1"
валидная неполная запись типа ".1" ".001" и ",1", такая же запись с лишними нулями ".10000", такая же с нулями и плюсом "+.0001"
разные неполные невалидные записи типа "." и "," и разные другие
десятичный разделитель без десятичной части "1." и "1,"
лишние и неверные разделители тысяч, например "1.00" и "1000." и "1.0.0" и "0.01"
Калькулятор Windows наверняка знаком каждому пользователю этой операционной системы и не требует особого представления. Теперь же любой пользователь может изучить исходный код калькулятора на GitHub и предложить свои улучшения.
Общественность, например, уже обратила внимание на такую функцию:
которая логирует текст из буфера обмена и, возможно, отправляет его на серверы Microsoft. Но эта заметка не об этом. Хотя подозрительных примеров кода будет много.
Про неправильное сравнение строк
V547 Expression 'm_resolvedName == L«en-US»' is always false. To compare strings you should use wcscmp() function. Calculator LocalizationSettings.h 180
Я просматриваю отчёты анализатора, сортируя их по возрастанию номеров диагностик, и предупреждение на этот код было самым первым в списке, и очень удачным.
Дело в том, что здесь неправильно сравниваются строки. Получилось сравнение указателей вместо значений строк. Сравнивается адрес массива символов с адресом строкового литерала. Указатели всегда неравны, поэтому условие всегда ложно. Для правильного сравнения строк следует использовать, например, функцию wcscmp.
Кстати, пока я пишу эту статью, в заголовочном файле массив символов m_resolvedName превратился в полноценную строку типа std::wstring. И теперь сравнение работает правильно. К моменту, когда вы будете читать эту статью, скорее всего, многие другие ошибки тоже будут исправлены благодаря энтузиастам и таким исследованиям, как это.
Утечка памяти в нативном коде
V773 The function was exited without releasing the 'temp' pointer. A memory leak is possible. CalcViewModel StandardCalculatorViewModel.cpp 529
Мы видим указатель temp, ссылающийся на массив из 100 элементов, под который выделена динамическая память. К сожалению, память освобождается всего в одном месте функции, во всех остальных местах возникает утечка памяти. Она не очень большая, но это всё равно ошибка для C++ кода.
Неуловимое исключение
V702 Classes should always be derived from std::exception (and alike) as 'public' (no keyword was specified, so compiler defaults it to 'private'). CalcManager CalcException.h 4
Анализатор обнаружил класс, унаследованный от класса std::exception через модификатор private (модификатор по умолчанию, если ничего не указано). Проблема такого кода заключается в том, что при попытке поймать общее исключение std::exception исключение типа CalcException будет пропущено. Такое поведение возникает потому, что приватное наследование исключает неявное преобразование типов.
Пропущенный день
V719 The switch statement does not cover all values of the 'DateUnit' enum: Day. CalcViewModel DateCalculator.cpp 279
Подозрительно, что в switch не рассмотрен случай с DateUnit::Day. Из-за этого в календарь (переменная m_calendar) не добавляется значение, связанное с днём, хотя метод AddDays у календаря присутствует.
- V719 The switch statement does not cover all values of the 'eANGLE_TYPE' enum: ANGLE_RAD. CalcManager trans.cpp 109
- V719 The switch statement does not cover all values of the 'eANGLE_TYPE' enum: ANGLE_RAD. CalcManager trans.cpp 204
- V719 The switch statement does not cover all values of the 'eANGLE_TYPE' enum: ANGLE_RAD. CalcManager trans.cpp 276
Подозрительные сравнение вещественных чисел
V550 An odd precise comparison: ratio == threshold. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. Calculator AspectRatioTrigger.cpp 80
Анализатор указал на подозрительное выражение ratio == threshold. Эти переменные типа double и точное сравнение таких переменных простым оператором равенства вряд ли возможно. Тем более, что значение переменной ratio получено после операции деления.
- V550 An odd precise comparison. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. CalcManager UnitConverter.cpp 752
- V550 An odd precise comparison: stod(roundedString) != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcManager UnitConverter.cpp 778
- V550 An odd precise comparison. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. CalcManager UnitConverter.cpp 790
- V550 An odd precise comparison: stod(roundedString) != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcManager UnitConverter.cpp 820
- V550 An odd precise comparison: conversionTable[m_toType].ratio == 1.0. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. CalcManager UnitConverter.cpp 980
- V550 An odd precise comparison: conversionTable[m_toType].offset == 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. CalcManager UnitConverter.cpp 980
- V550 An odd precise comparison: returnValue != 0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcManager UnitConverter.cpp 1000
- V550 An odd precise comparison: sizeToUse != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcViewModel LocalizationService.cpp 270
- V550 An odd precise comparison: sizeToUse != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcViewModel LocalizationService.cpp 289
- V550 An odd precise comparison: sizeToUse != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcViewModel LocalizationService.cpp 308
- V550 An odd precise comparison: sizeToUse != 0.0. It's probably better to use a comparison with defined precision: fabs(A — B) > Epsilon. CalcViewModel LocalizationService.cpp 327
- V550 An odd precise comparison: stod(stringToLocalize) == 0. It's probably better to use a comparison with defined precision: fabs(A — B) < Epsilon. CalcViewModel UnitConverterViewModel.cpp 388
Подозрительная последовательность функций
V1020 The function exited without calling the 'TraceLogger::GetInstance().LogNewWindowCreationEnd' function. Check lines: 396, 375. Calculator App.xaml.cpp 396
Диагностика V1020 анализирует блоки кода и эвристически пытается найти ветви, в которых забыт вызов функции.
В приведённом выше фрагменте кода анализатор нашёл блок с вызовом функций LogNewWindowCreationBegin и LogNewWindowCreationEnd. Ниже он нашёл похожий блок кода, в котором функция LogNewWindowCreationEnd вызывается только при определённых условиях, что подозрительно.
Ненадёжные тесты
V621 Consider inspecting the 'for' operator. It's possible that the loop will be executed incorrectly or won't be executed at all. CalculatorUnitTests UnitConverterViewModelUnitTests.cpp 500
Анализатор обнаружил цикл for, в котором не выполняется ни одна итерация, а, следовательно, не выполняются и тесты. Начальное значение счётчика цикла button (93) сразу превышает конечное (0).
V760 Two identical blocks of text were found. The second block begins from line 688. CalculatorUnitTests UnitConverterViewModelUnitTests.cpp 683
Ещё один тест с подозрительным кодом. Анализатор обнаружил идентичные фрагменты кода, выполняющиеся друг за другом. Возможно, код писался копированием этих фрагментов, но программист забыл изменить часть кода.
V601 The 'false' value is implicitly cast to the integer type. Inspect the second argument. CalculatorUnitTests CalcInputTest.cpp 352
В функцию ToRational передают булевское значение false, хотя параметр имеет тип int32_t и называется precision.
Я решил отследить используемое значение в коде. Далее оно передаётся в функцию StringToRat:
а затем в StringToNumber:
И вот тело нужной функции:
Тут мы видим, что переменная precision стала называться starting и участвует в выражении cdigits > starting, что очень странно, ведь туда изначально передали значение false.
Избыточность
V560 A part of conditional expression is always true: NumbersAndOperatorsEnum::None != op. CalcViewModel UnitConverterViewModel.cpp 991
Переменная op уже сравнивалась со значением NumbersAndOperatorsEnum::None и дублирующую проверку можно удалить.
V728 An excessive check can be simplified. The '(A && B) || (!A && !B)' expression is equivalent to the 'bool(A) == bool(B)' expression. Calculator Calculator.xaml.cpp 239
Это гигантское условное выражение изначально имело ширину 218 символов, но я разбил его на несколько строк для демонстрации предупреждения. А переписать код можно до такого короткого и, главное, читабельного варианта:
V524 It is odd that the body of 'ConvertBack' function is fully equivalent to the body of 'Convert' function. Calculator BooleanNegationConverter.cpp 24
Анализатор обнаружил две функции, которые реализованы одинаково. По названиям функций Convert и ConvertBack можно предположить, что они должны выполнять разные действия, но разработчикам виднее.
Заключение
Наверное, каждый открытый проект от Microsoft давал нам возможность показать важность применения методологии статического анализа. Даже на таких маленьких проектах, как калькулятор. В таких крупных компаниях, как Microsoft, Google, Amazon и других, работает много талантливых программистов, но они такие же люди, которые делают ошибки в коде. Применение инструментов статического анализа кода — один из хороших способов повысить качество программ в любых командах разработчиков.
Проверь свой «Калькулятор», скачав PVS-Studio и попробовав на своём проекте. :-)
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Svyatoslav Razmyslov. Counting Bugs in Windows Calculator
После установки различных программ, игр и приложений в операционной системе Windows 7 некоторые пользователи сталкиваются с проблемой. Заключается она в некорректной работе одной из стандартных программ – калькулятором.
Проблема с калькулятором в Windows 7 заключается в том, что поле отображения вводимых цифр имеет половинный размер и каждое вновь вводимое значение наслаивается на предыдущее. В таком случае считать полученные данные чрезвычайно сложно, а порой и невозможно.
Ошибка стандартного калькулятора в Windows 7
Данный глюк калькулятора в Windows 7, как правило, появляется после установки различных приложений и программ, таких как игры, например. Особенно это имеет место, если программы, мягко говоря “взломанные”, то есть нелицензионные.
Несмотря на то, что стандартный калькулятор нужен не всегда и необходимость им воспользоваться возникает довольно редко, всё же огорчает тот факт, что его в необходимых случаях нет под рукой.
Поэтому рассмотрим процесс, с помощью которого можно устранить глюк калькулятора в Windows 7.
Причиной возникновения “урезанного” окна в калькуляторе является замена стандартных шрифтов на другие при установке какой-либо программы. Именно из-за этого и происходит неправильное отображение окна ввода и путаница цифр.
Для того чтобы устранить проблему, необходимо восстановить первоначальные значения в реестре операционной системы. Процедура эта совсем не сложная, но довольно ответственная. Как известно, в реестре хранятся настройки операционной системы, и неправильное редактирование значений реестра может обернуться её неработоспособностью. Поэтому производить все операции необходимо аккуратно и точно .
Итак, для редактирования реестра в Windows 7 нужно запустить редактор реестра. Делается это также как и в Windows XP:
“Пуск” – “Все программы” – “Стандартные” – “Выполнить”. Появиться окно "Выполнить".
Стандартная программа "Выполнить"
В него вводим название программы, которую хотим запустить – regedit.exe – жмём ОК.
Запуск "Редактора реестра"
Появиться окно программы “Редактор реестра”.
Окно "Редактора реестра"
Далее щёлкаем на стрелочки рядом с папкой. При щелчке будут показаны вложенные папки. Таким образом, следуем по пути:
“HKEY_LOCAL_MACHINE” – “SOFTWARE” – “Microsoft” – “Windows NT” – “CurrentVersion”. Далее находим папку “FontSubstitutes” и кликаем по ней. В правой части окна будут показаны параметры и значения. Их то мы и будем редактировать.
В правой части окна в алфавитном порядке будут показаны параметры. В колонке “Значение” будут указаны присвоенные шрифты. В колонке “Имя” находим MS Shell Dlg,204.
Внимание ! Надо найти именно этот пункт! Здесь легко допустить ошибку, так как рядом будут другие параметры с похожим названием (MS Shell Dlg; MS Shell Dlg 2; MS Shell Dlg,0). Изменять значение необходимо у параметра MS Shell Dlg,204 иначе результата не будет.
Параметр реестра "MS Shell Dlg,204"
Изменяем значение с MS Sans Serif,204 на Microsoft Sans Serif,204. Для этого щёлкаем правой кнопкой мыши на MS Shell Dlg,204 и выбираем пункт “Изменить…”. Откроется окно “Изменение строкового параметра”. В поле “Значение” вводим Microsoft Sans Serif,204. Изменяем MS на Microsoft.
Изменение строкового параметра
Для того чтобы изменения, внесённые в реестр вступили в силу – перезагружаем компьютер.
Затем проверяем, пропал ли глюк калькулятора. Если всё сделано верно, то, как правило, проблема устраняется, и калькулятор восстанавливает свою прежнюю работоспособность.
Людям свойственно ошибаться, признаваться в своих ошибках не любит никто. Поэтому человечество и придумало множество приспособлений и технических средств, чтобы минимизировать возможные ошибки, упростить и ускорить процесс принятия решений и точность выполнения разнообразных процессов и вычислений. Но теоретически умные электронные устройства и программы тоже могут ошибаться и работать не точно.
Поэтому стоит подстраховываться и заранее проверять точность вычислений выбранных устройств.
Попробуем это сделать на примере обычного калькулятора. Сегодня калькуляторы можно найти везде – в телефонах, часах, плеерах, других электронных устройства, кроме того калькулятор, как самостоятельное устройство тоже никто не отменял.
Общие сведения
Этот инструмент расчетов будет востребованным еще долгое время, вероятнее всего, чем дальше, тем более востребованным он будет становиться. Калькулятор нужен студентам и школьникам, менеджерам и бухгалтерам, домохозяйкам и инженерам.
Сегодня найти в продаже калькулятор довольно легко, кроме того, он чаще всего встроен в другие электронные устройства. А наши родители только мечтали о таком чуде техники, которая делает сложные вычисления за пару секунд. Жизнь студентов, школьников, домохозяек и инженеров стала легче только в 1970х года, когда появились в свободной продаже компактные калькуляторы (их компактность и эргономичность с современными уже никак не сравнить).
Калькуляторы бывают разных типов:
- Обычный с минимальным набором возможных функций – подходит для большинства пользователей, способен отлично справляться с простыми задачами, отлично подойдет для школьников и тех, кому он нужен для элементарных вычислений.
- Бухгалтерский калькулятор, как видно из названия предназначен для специалистов в сфере бухгалтерии, как правило, он настольный, имеет специальные «денежные» кнопки, а так же специфические функции, например, автоматического округления, возможность автоматического вычисления прибыли и другие.
- Программируемый или инженерный калькулятор – имеет большое количество дополнительных функций, который могут производить довольно сложные вычислительные процедуры. Отличительной особенностью данного типа является возможность индивидуального программирования.
- Банковский или финансовый калькулятор – ориентирован на специфические банковские операции, например, для расчета процентов.
- Графический калькулятор способен выводить на дисплей графики и рисунки.
Любой калькулятор должен быть заключен в прочный корпус, иметь емкий аккумулятор, достаточное количество цифровых ячеек на дисплее. Сегодня вообще калькуляторы встраиваются в любое мобильное устройство от часов до компьютера. Так или иначе, внешний вид калькулятора, по сути, мало чем отличается от первых образов. Это дисплей, где отражаются вводные данные и результаты вычислений, и клавиатура, для введения этих самых данных. Все процессоры и микросхемы спрятаны внутри корпуса устройства. Главное в любом вычислительном устройстве – точность и надежность самих вычислений.
Простые способы проверить работоспособность и точность работы калькулятора
Перед использованием калькулятора или его покупкой стоит произвести простые вычислительные действия. Сделать это можно легко в любой момент, когда у вас появиться подобная потребность или возникнут сомнения в правильности выполненных расчетов. Никаких дополнительных инструментов и приспособлений не понадобиться – достаточно только самого калькулятора.
Простые способы
12345679*9 = 111111111
12345679*18 = 222222222
12345679*27 = 333333333
12345679*36 = 444444444
12345679*45 = 555555555
12345679*54 = 666666666
12345679*63 = 777777777
12345679*72 = 888888888
12345679*81 = 999999999
- Последовательное введение данных следующего алгебраического примера 100*10/2+16*4 должно отобразить на экране ответ в виде числа 564. Это так же говорит о корректности его вычислений и должно снимать вопросы с точностью его работы.
Серьезные способы проверки работы калькулятора
Бывают ситуации, когда нужна абсолютная уверенность в точности работы вычислительного устройства, например, при расчете в научных или технических процессов. Тут будет крайне важна точность, а не приблизительность вычислений. Как показывает практика, вычисления на простых бытовых калькуляторах могут выдавать довольно существенные погрешности в десятки, а иногда и сотни раз. Для определения точности расчетов вычислительного устройства использует более сложная формула. Вводить ее важно не частями, а сразу целым массивом данных.
Если полученный ответ приблизительно будет равен «-1», то можно смело доверять вашему калькулятору самые сложные расчеты, и не беспокоиться за точность вычислений.
Стоит отметить, что с таким вычислением не справляется большинство самых современных калькуляторов. Если вам точность очень важна, а калькулятор отказывается вам в этом помогать, то можно воспользоваться современными компьютерными программами, которые имитируют вычислительные процессы и гарантируют точность результатов.
Что еще важно при выборе калькулятора?
Проверять калькулятор стоит при самом начале его использования, еще лучше до покупки, чтобы обезопасить себя от возможных ошибок. Кроме работы процессора и точности вычислений, стоит обратить внимание на величину дисплея, его контрастность – дисплей должен вмещать необходимое вам количество данных и показывать их четко при самом ярком или тусклом освещении.
Информация на клавишах так же должна быть нанесена качественно – четко и разборчиво, кроме того краска должна быть стойкой к стиранию при длительном использовании, а шрифт достаточно крупным и читаемым, кнопки должны располагаться в удобных и привычных местах, нажиматься легко и плавно. Иначе вы рискуете постоянно сбиваться при вводе данных, что приведет к процессу затягивания вычислений.
Как правило, качественное устройство имеет хорошую фирменную упаковку и инструкцию по эксплуатации. Кстати, в самой инструкции производители довольно часто указывают способы проверки точности калькулятора. При покупке стоит обратить внимание и на сроки гарантии, чтобы при обнаружении неисправности обменять калькулятор на более качественный или вернуть свои деньги.
Читайте также: