На чтение 3 мин Просмотров 1к. Опубликовано 08.09.2021
Тока не смейтесь. 😳
В магазине Комус куплен калькулятор Casio на фирму. Так вот, эта падла неправильно считает проценты. :kto: Обнаружено случайно — бухгалтера сделали мне замечание, мол, ты чо? Хорошо, что сейчас всплыло, а не через год работы этим калькулятором :!a:
А именно: «100» «+» «20» «%» (если набрать такую комбинацию) должно получиться 120. Он выдаёт 125.
Иду в Комус, продавец в лёкгом шоке. :tik Проверили на калькуляторе другой фирмы — там всё чётко. Забрали на эксперитизу.
Умные люди надоумили слупить с Casio лимон баксов — мол, из-за неправильных подсчётов денег ( а что ещё считать на калькуляторе?) на вашем грёбаном калькуляторе потерперпел убытки. Плюс скандал.
Чо думаете? Звонил Саше НМХ — на звонок не ответил. #-o
Дубликаты не найдены
А я в гугле проверил
можно ещё 12345679*8
Так-то сейчас актуально стало с учетом распространения программ калькуляторов на плэймаркете от разных багоделов.
Комментарий дня
Получается, что белые — это негры с нарушенной пигментацией?)
Калькуляторы сегодня встраиваются буквально во все: в часы, телефоны, смартфоны, плееры и прочие электронные устройства. Однако калькулятор, как самостоятельное устройство будет востребован еще очень долго.
Он необходим школьникам и студентам, домохозяйкам и бухгалтерам, инженерам и менеджерам.
Купить калькулятор, подходящий именно вам, несложно, нужно только четко знать, какой именно калькулятор нужен.
Существуют разные типы подобных устройств:
Обычный (простейший) с минимальным набором функций. Подойдет для школьников и для тех, кто выполняет обычно несложные вычисления.
Бухгалтерский – как правило, настольный с крупными кнопками. Имеет специальные «денежные» кнопки, автоматическое округление и т. п.
Банковский (финансовый) – предназначен для подсчета процентов и других специфических операций.
Инженерный и программируемый калькулятор имеют множество функций и позволяют производить сложные вычисления. Имеют возможность программирования пользователем.
Разумеется, калькулятор должен иметь прочный корпус, емкую батарею, достаточное количество разрядов на дисплее. Но главное в работе любого вычислительного устройства – точность и надежность.
Как проверить калькулятор?
Существует несколько несложных способов, позволяющих выяснить, не «врет» ли устройство. Прежде всего: попробуйте перемножить или сложить максимально большие числа.
Если калькулятор не выдаст сообщение об ошибке и не сломается – отлично, самый первый тест пройден.
Задайте несколько примеров на сложение, несложных, типа: 3+6=9. Затем сложнее: 1111х1111=1234321.
Почему именно такой пример? А его запомнить просто! Или еще: 11111х11111=123454321. Есть пример на вычитание: 12345678-123456789=-111111111.
Существуют и другие формулы проверки, которые ничем не отличаются от любых других, кроме того, что легко запоминаются:
- 12345679х9=111111111
- 123123123 : 1001001=123
- 12345679х8=98765432
А вот еще один интересный способ — 12345679*7,2 получится 88888888888 то есть все восьмёрки, сразу видно, что логика не сбита и дисплей весь рабочий!
Проверка калькулятора не займет много времени. Однако если калькулятор нужен для проведения инженерных расчетов, применения функций и т. п., то и проверять нужно именно их. Еще по теме:
Эта статья — продолжение истории про калькулятор на JavaScript. В предыдущих частях мы:
- написали простой калькулятор на JavaScript;
- отдали его UX-тестировщикам и обновили дизайн калькулятора по их замечаниям.
Теперь наш калькулятор будут смотреть инженеры по тестированию — постараются найти в нём ошибки логики, поведения, вычислений и прочие неявные моменты.
👉 В этой статье не будет автотестов, юнит-тестов, API-тестов и интеграционных тестов. Это всё нужные инструменты, но задача тестировщика, в частности, — выбрать правильный инструмент тестирования.
Если у него в работе очень простая программа (как наш калькулятор), то нет смысла городить автоматизацию и делать тесты ради тестов. Иногда можно и вручную всё проверить и получить точно такой же результат.
Базовое тестирование
Первое, что мы делаем, — проверяем, а как вообще ведут себя кнопки математических действий и делают ли они то, что нужно. Возьмём два числа — 12 и 5 — и сравним результаты всех действий с тем, что даёт калькулятор:
12 + 5 = 17
12 − 5 = 7
12 × 5 = 60
12 / 5 = 2,4
Отрицательные числа тоже отображаются и считаются правильно.
Тестируем большие числа
У компьютеров есть нюанс: любые переменные имеют ограничения по размеру числа. Например, если на переменную выделено 16 бит, то максимальное число, которое можно в нее положить, — 65 536. Число на единицу больше уже потребует 17 бит, а мы столько не выделяли.
Мы хоть и разработчики этого калькулятора, но мы не помним, какое число имели в виду, когда заводили переменную. Может быть, это решение за нас принял JavaScript. Поэтому нужно проверить, не сломается ли наш калькулятор от больших чисел.
Пробуем: 123 456 789 × 2 = 246 913 578 — верно
А вот необычный эксперимент:
12 345 678 901 234 567 × 1 = 12 345 678 901 234 568
Ух ты! Мы умножили большое число на единицу, а в ответе появилась ошибка. Это значит, что настолько длинные числа за раз наш калькулятор уже обработать не в состоянии.
Записываем баг:
❌ Неправильно обрабатываются 17-значные числа и те, которые больше них.
А если мы попробуем получить 17-значное число в ответе, интересно, оно тоже будет с ошибкой?
Да, в ответе тоже неверное число — 8 × 4 = 32, поэтому в конце должно стоять 2, а не 0. Пишем баг:
❌ Если в ответе получается 17-значное число или более — ответ точно неверный.
При этом деление на 16-значное число работает верно:
Тестирование математических трюков
Теперь попробуем разделить на ноль:
Скрипт хитро выкрутился и записал результатом деления бесконечность. Но лучше выводить сообщение, что на ноль делить нельзя.
❌ Нет сообщения при делении на ноль.
Отказоустойчивость
А что если оставить поле ввода пустым и попробовать что-то посчитать? Давайте посмотрим:
Скрипт преобразовал пустую строку в ноль и получил ответ, но это неправильно — при отсутствии одного из чисел калькулятор должен сообщить об этом, а не продолжать считать.
❌ Нет сообщения, если одно из чисел не введено.
Пойдём дальше и введём слово вместо числа:
Скрипт честно пытается перевести строку в число, у него это не получается, поэтому он выдаёт неопределённое значение.
❌ Нет проверки на то, ввели число или строку.
И напоследок проверим что будет, если мы что-то введём, но не выберем ни одно действие:
Тоже плохо. Надо будет обработать такую ситуацию.
❌ Нет проверки, когда не выбрали ничего из математических действий.
Так проверяем работу калькулятора со всеми действиями, а не только с умножением. В итоге у нас получится список ошибок, которые нужно исправить.
Что делаем
После тестирования у нас получился такой список ошибок:
❌ Неправильно обрабатываются 17-значные числа и те, которые больше них.
❌ Если в ответе получается 17-значное число или более — ответ точно неверный.
❌ Нет сообщения при делении на ноль.
❌ Нет сообщения, если одно из чисел не введено.
❌ Нет проверки на то, ввели число или строку.
❌ Нет проверки, когда не выбрали ничего из математических действий.
Исправим эти ошибки. Так как все вычисления начинаются при вызове функции func(), то и править всё будем тоже внутри неё.
Проверяем, что ввели число, а не слова или другие символы
Для перевода строку в число в JavaScript используют функцию Number(). Если строку можно перевести в число — она сработает без ошибок, а если не получится — вернёт значение NaN. Это значит, что числа не получилось.Чтобы проверить, прошло всё нормально или нет, мы будем использовать функцию isNaN() — она сравнит значение переменной с NaN, и вернёт true, если в переменной лежит NaN. А чтобы не путать числа и строки для сравнения, переименуем переменные в самом начале скрипта и сделаем их принудительно строками:
// получаем первое и второе число
var num1_str = String(document.getElementById("num1").value);
var num2_str = String(document.getElementById("num2").value);
// переводим строки в числа
let num1 = Number(num1_str)
let num2 = Number(num2_str)
// проверяем, получилось ли число из первой строки или нет
if (isNaN(num1)) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор не может распознать первое число. Проверьте его, пожалуйста';
// и выходим из функции
return;
}
// проверяем, получилось ли число из второй строки или нет
if (isNaN(num2)) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор не может распознать второе число. Проверьте его, пожалуйста';
// и выходим из функции
return;
}
Проверяем, что нет пустых значений
JavaScript когда переводит строку в число, то пустую строку он считает как 0. Нам такой вариант не подходит, поэтому сравним её с пустой сторокой. Если она пустая — выдаём сообщение и ничего не считаем.
Ещё надо дополнительно добавить проверку на пробелы — JavaScript строку из пробелов тоже переводит как ноль, а нам это не нужно:
// получаем первое и второе число
var num1_str = String(document.getElementById("num1").value);
var num2_str = String(document.getElementById("num2").value);
// проверяем, не пустая ли первая строка
if ((num1_str.length == 0) || (num1_str.indexOf(' ') != -1)) {
// если пустая — пишем сообщение
document.getElementById("result").innerHTML = 'Вы не ввели первое число или добавили пробел в поле ввода';
// и выходим из функции
return;
}
// проверяем, не пустая ли вторая строка
if ((num2_str.length == 0) || (num2_str.indexOf(' ') != -1)) {
// если пустая — пишем сообщение
document.getElementById("result").innerHTML = 'Вы не ввели второе число или добавили пробел в поле ввода';
// и выходим из функции
return;
}
Обрабатываем деление на ноль
Простая проверка — добавляем сравнение второго числа с нулём:
// проверяем второе число при делении
if ((num2 == 0) && (op == '/')) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'На ноль делить нельзя';
// и выходим из функции
return;
}
Обрабатываем длинные числа
Даже если мы ограничим каждое поле ввода числами по 16 знаков вместо 17, то при перемножении они дадут нам в ответе 32 знака — а это тоже превышает наш предел точности. Чтобы гарантированно получить в ответе число не больше 16 разрядов перед запятой, нам нужно, чтобы оба числа были не больше 99 999 999 — в нём 8 разрядов, а при перемножении мы получим максимум 16, как раз то, что нужно.
Чтобы это сделать, добавим проверку на размер числа:
// проверяем размер чисел
if ((num1 > 99999999) || (num2 > 99999999)) {
// если не помещается одно из них в диапазон — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор может работать с числами не больше 99 999 999';
// и выходим из функции
return;
}
Если не выбрано математическое действие
С этим всё просто — добавляем в case действие по умолчанию, которое выполнится, если никакие из вариантов не подойдут:
// смотрим, что было в переменной с действием, и действуем исходя из этого
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
default: result = 'Выберите действие'
}
В итоге
✅ Калькулятор не работает с числами больше 16 знаков до запятой и предупреждает об этом пользователя
✅ В ответе всегда число, в котором не больше 16 знаков до запятой
✅ Есть проверка деления на ноль
✅ Есть сообщение, если одно из чисел не введено.
✅ Есть проверка на то, ввели число или строку.
✅ Есть проверка, когда не выбрали ничего из математических действий.
Это всё?
О нет, этот калькулятор можно гонять ещё и в хвост и в гриву:
- Протестировать десятичные дроби и операции с ними.
- Вставлять в поля ввода изображения и файлы.
- Устраивать переполнение буфера браузера.
- Совершать 10 миллионов вычислений в секунду.
- Запускать одновременно 10 миллионов калькуляторов.
- Запустить калькулятор в 1911 году.
- Засунуть в него комплексные числа.
- Засунуть в него самое большое простое число (и разделить).
- Засунуть в него кота.
Это (и многое другое) — и есть работа тестировщика. Круто, да?
Приходите учиться на тестировщиков
в «Практикум» →
И ни одна кошка не пострадает.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Размеры шрифтов</title>
<style type="text/css">
/*задаём общие параметры для всей страницы: шрифт и отступы*/
body {
text-align: center;
margin: 10;
font-family: Verdana, Arial, sans-serif;
font-size: 16px;
}
/* настраиваем внешний вид полей ввода*/
input {
display: inline-block;
margin: 20px auto;
border: 2px solid #eee;
padding: 10px 20px;
font-family: Verdana, Arial, sans-serif;
font-size: 16px;
}
/* внешний вид кнопок */
button{
font-family: Verdana, Arial, sans-serif;
font-size: 16px;
margin: 10px;
padding: 10px;
}
/* стиль подсветки выбранной операции */
.light{
background-color: yellow;
}
</style>
</head>
<body>
<!-- заголовок -->
<h1>Калькулятор</h1>
<!-- поле ввода первого числа -->
<input id="num1" />
<!-- блок с кнопками -->
<div id="operator_btns">
<button id="plus" onclick="sel_ligth('plus')">+</button>
<button id="minus" onclick="sel_ligth('minus')">-</button>
<button id="times" onclick="sel_ligth('times')">x</button>
<button id="divide" onclick="sel_ligth('divide')">:</button>
</div>
<!-- поле ввода второго числа -->
<input id="num2" />
<br>
<!-- кнопка для расчётов -->
<button onclick="func()">Посчитать</button>
<!-- здесь будет результат -->
<p id="result"></p>
<!-- наш скрипт -->
<script>
// переменная, в которой хранится выбранное математическое действие
var op;
// функция, которая подсветит выбранное математическое действие
function sel_ligth(sel_id) {
// убираем класс подсветки со всех кнопок
document.getElementById("plus").classList.remove("light");
document.getElementById("minus").classList.remove("light");
document.getElementById("times").classList.remove("light");
document.getElementById("divide").classList.remove("light");
// и добавляем его только к нажатой
document.getElementById(sel_id).classList.add("light");
// в зависимости от нажатой клавиши меняем значение переменной op
switch (sel_id) {
case "plus":
op = "+"
break;
case 'minus':
op = '-'
break;
case 'times':
op = "*"
break;
case 'divide':
op = "/"
break;
}
}
// добавляем обработчик нажатия на клавиши ко второму полю ввода
document.getElementById("num2").addEventListener('keydown', function(e) {
if (e.keyCode === 13) {
func();
}
});
// функция расчёта
function func() {
// переменная для результата
var result;
// получаем первое и второе число
var num1_str = String(document.getElementById("num1").value);
var num2_str = String(document.getElementById("num2").value);
// проверяем, не пустая ли первая строка
if ((num1_str.length == 0) || (num1_str.indexOf(' ') != -1)) {
// если пустая — пишем сообщение
document.getElementById("result").innerHTML = 'Вы не ввели первое число или добавили пробел в поле ввода';
// и выходим из функции
return;
}
// проверяем, не пустая ли вторая строка
if ((num2_str.length == 0) || (num2_str.indexOf(' ') != -1)) {
// если пустая — пишем сообщение
document.getElementById("result").innerHTML = 'Вы не ввели второе число или добавили пробел в поле ввода';
// и выходим из функции
return;
}
// переводим строки в числа
let num1 = Number(num1_str)
let num2 = Number(num2_str)
// проверяем, получилось ли число из первой строки или нет
if (isNaN(num1)) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор не может распознать первое число. Проверьте его, пожалуйста';
// и выходим из функции
return;
}
// проверяем, получилось ли число из второй строки или нет
if (isNaN(num2)) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор не может распознать второе число. Проверьте его, пожалуйста';
// и выходим из функции
return;
}
// проверяем размер чисел
if ((num1 > 99999999) || (num2 > 99999999)) {
// если не помещается одно из них в диапазон — пишем сообщение
document.getElementById("result").innerHTML = 'Калькулятор может работать с числами не больше 99 999 999';
// и выходим из функции
return;
}
// проверяем второе число при делении
if ((num2 == 0) && (op == '/')) {
// если не получилось — пишем сообщение
document.getElementById("result").innerHTML = 'На ноль делить нельзя';
// и выходим из функции
return;
}
// смотрим, что было в переменной с действием, и действуем исходя из этого
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
default: result = 'Выберите действие'
}
// отправляем результат на страницу
document.getElementById("result").innerHTML = result;
}
</script>
</body>
</html>
Посмотреть работу калькулятора на странице проекта.
Что дальше
Кажется, что теперь в самом коде есть что улучшить. В следующей серии займёмся рефакторингом. Не переключайтесь.
Вёрстка:
Кирилл Климентьев
Да, калькуляторы могут ошибаться. Это не что иное, как простые компьютеры, и поэтому они хороши ровно настолько, насколько хорош их код, и всегда будут иметь некоторые ограничения, например, округление. Некоторых ошибок можно избежать, если обратить внимание на то, как вы вводите проблему, если вы знаете об ошибке в кодировке.
Точно так же, как вы разбиваете 24? Разбейте 24 на части: 20 + 4. Из исходного числа вычтите 20: 83 – 20 = 63. Из ответа вычтите 4: 63 – 4 = 59.
Что такое секретный калькулятор? Приложение Secret Calculator выглядит как невинное приложение-калькулятор на устройстве Iphone или Android вашего ребенка. Собственно, это приложение используется для скрытия файлов, фото и видео. … Это приложение популярно, потому что оно помогает любому скрыть изображения, фотографии и файлы в папке, которую невозможно найти.
Всегда ли работают калькуляторы? Я думаю, что большинство людей сказали бы, что за исключением любого физического повреждения калькулятора (падение, воздействие сильной жары или холода и т. д.), все калькуляторы точны в 99.99% случаев. Тем не менее, один из способов, который вы можете изучить, — это то, сколько десятичных знаков показывает калькулятор.
Во-вторых, калькуляторы перестают работать? Ожидайте вашего портативный калькулятор, который прослужит вам не менее 5-10 лет, и не удивляйтесь, если он переживет свой ожидаемый срок службы! В общем, если у вас есть калькулятор на солнечной энергии, вы, вероятно, столкнетесь с другими проблемами, прежде чем батарея разрядится.
Вы можете сломать 18?
Множители 18 — это список целых чисел, который можно без остатка разделить на 18. Всего он состоит из 6 факторов, из которых 18 является самым большим фактором, а положительные факторы 18 — это 1, 2, 3, 6, 9 и 18. Парные факторы 18 — это (1, 18), (2, 9) и (3, 6), а его основные факторы равны 1, 2, 3, 6, 9, 18.
тогда Как вы делаете десятку, чтобы решить 14 6?
Как расстаться в 56?
Как вы используете Хикалькулятор?
Пользователи Calculator + Vault просто нажмите числовой код и введите символ процента, чтобы разблокировать приложение и получить доступ к своим скрытым файлам. Calculator + позволяет пользователям переносить фотографии и видео прямо из галереи своего устройства в приложение хранилища или снимать фотографии и видео прямо в приложении.
Как выглядит поддельное приложение-калькулятор? Иконки приложений выглядят похож на настоящий калькулятор iPhone, а когда они открыты, они функционируют как калькулятор. Введите код, и откроется фотохранилище. Снимки, сделанные внутри приложения, остаются там и не видны в фотопленке iPhone.
Как открыть калькулятор приложения хранилища?
Может ли калькулятор разрядиться? Но предположение, что калькуляторы никогда не разряжаются, это просто ложь. Современные калькуляторы потребляют очень мало энергии. В качестве батарейки они используют одну или две кнопочные батарейки LR44 или одну ячейку AA/AAA. Особенно, если он использует элемент AA, он длится в основном неопределенно долго.
Как сделать калькулятор неверным?
Что внутри калькулятора?
Большинство калькуляторов изготовлены из прочного пластика, известного как акрилонитрилбутадиенстирол (АБС). Вы также найдете калькуляторы более высокого класса, изготовленные из нержавеющей стали, алюминия или латуни.
Солнечные калькуляторы подделка? Солнечные калькуляторы используют жидкокристаллические дисплеи, поскольку они энергоэффективны и способны работать в диапазоне низкого напряжения 1.5–2 В. … По состоянию на 2010-е годы некоторые дешевые калькуляторы включают «фиктивный«солнечная панель», подразумевая, что они питаются от солнечной энергии, но на самом деле они питаются только от батареи.
Может ли калькулятор разрядиться? Но предположение, что калькуляторы никогда не разряжаются, это просто ложь. Современные калькуляторы потребляют очень мало энергии. В качестве батарейки они используют одну или две кнопочные батарейки LR44 или одну ячейку AA/AAA. Особенно, если он использует элемент AA, он длится в основном неопределенно долго.
Есть ли в калькуляторах Casio солнечные батареи?
Почти каждый базовый калькулятор имеет встроенный набор солнечных батарей.. Тем не менее, эти калькуляторы обычно поставляются с батареей внутри, которая фактически питает устройство. Эти панели помогают продлить срок службы калькулятора за счет медленной подзарядки оригинальной батареи.
Что значит уменьшать и вычитать? Минуты: количество или число, из которого следует вычесть другое. Вычитаемое: количество или число, которое нужно вычесть из другого.
Почему число 41 является простым числом?
Да, 41 — простое число. Номер 41 делится только на 1, а само число. … Так как 41 имеет ровно два множителя, то есть 1 и 41, это простое число.
Как расстаться в 13?
Как научить вычитанию до 20?
Что такое факт 10+? Добавление десяти фактов (10 + 3, 7 + 10) применяется, когда 10 добавляется к однозначному числу. Эта стратегия помогает учащимся гибко работать с десятками и единицами. Добавить Девять фактов быстро, если вы знаете, как составить 10. Если факт равен 9 + 7, как в примере, составьте 10 (9+1=10), а затем добавьте еще 6.
Как сделать 10 или 100, чтобы вычесть мысленно?
Содержание
- Ошибки калькулятора
- 19. Ошибка MOD_DIV.
- 20. Ошибка E_TO_FP.
- 21. Ошибка INKEY$#0.
- Почему калькулятор неправильно считает
- Дубликаты не найдены
- Комментарий дня
- Подсчитаем баги в калькуляторе Windows
- Введение
- Про неправильное сравнение строк
- Утечка памяти в нативном коде
- Неуловимое исключение
- Пропущенный день
- Подозрительные сравнение вещественных чисел
- Избыточность
- Заключение
Ошибки калькулятора
Теперь рассмотрим несколько ошибок, связанных со встроенным в ПЗУ калькулятором. О некоторых из них мы так или иначе уже упоминали в своих прочих работах.
19. Ошибка MOD_DIV.
Эта ошибка связана с работой кода калькулятора 32h. По этой команде со стека калькулятора должны сниматься два верхних пятибайтных числа, например x и y и вместо них на стек должны отправляться
x MOD y и x DIV y
(именно в этом порядке).
Напомним, что x MOD y это остаток от целочисленного деления x на y, а x DIV y это целая часть частного от деления x на y.
x MOD y = x y*INT(x/y) x DIV y = INT (x/y)
В своих расчетах процедура, обслуживающая эту функцию калькулятора, использует нулевую ячейку памяти калькулятора M0, а с этой ячейкой есть одна особенность. Дело в том, что при вычислении функции INT эта ячейка коррумпируется, если аргумент при INT меньше нуля. Таким образом, функция MOD_DIV калькулятора дает неверный результат, когда x/y число отрицательное.
Ошибки могло бы и не быть, если бы процедура, занимающаяся расчетом этой функции (а она расположена в ПЗУ по адресу 36A0H = 13964 DEC) использовала бы в своих расчетах не нулевую ячейку памяти калькулятора, а первую (M1).
20. Ошибка E_TO_FP.
В системе команд калькулятора есть команда с кодом 3C. Ее назначение умножение числа, находящегося на вершине стека калькулятора на множитель, равный 10 в степени A, где A содержимое аккумулятора микропроцессора.
Вся неприятность в том, что калькулятор после своего включения командой RST 28 не резервирует содержимое аккумулятора, в отличие от содержимого регистра B. Поэтому, к тому времени, как вы воспользуетесь командой калькулятора 3C, есть большая вероятность того, что в аккумуляторе будет не подготовленное вами число, а что то совсем другое.
Единственный выход выйти из калькулятора, прогрузить аккумулятор нужным Вам числом, выполнить нужное умножение вызовом процедуры ПЗУ E_TO_FP и снова вернуться в калькулятор:
LD A, xx CALL 2D4FH RST 28
Процедура E_TO_FP находится в ПЗУ по адресу 2D4FH = 11599 DEC.
21. Ошибка INKEY$#0.
Обычно нулевой поток представляет собой клавиатуру, поэтому естественно предположить, что INKEY$#0 то же самое, что и просто INKEY$ без номера потока.
Тем не менее это не так, и почти необратимо INKEY$#0 выдает пустую символьную строку, что делает эту функцию полностью бесполезной.
Надо также заметить, что в системе команд калькулятора есть команда с кодом 1А, которая служит для расчета функции INKEY$#X, где X число, содержащееся на вершине стека калькулятора. И эта команда калькулятора будет бесполезной, если поток X представляет клавиатуру.
Ошибка находится в подпрограмме ПЗУ по адресу 1634Н=5684 DEC, которая устанавливает канал «X» текущим каналом. В этой подпрограмме по адресу 1638К стоит ошибочная команда RES 5,(FLAGS), выключающая пятый бит системной переменной FLAGS. в результате этого ошибочно отбивается любое нажатие клавиши вместо того, чтобы быть принятый к рассмотрению.
Ошибку можно было бы исправить, если в подпрограмме READ_IN (3645Н = 13893 DEC) сохранить значение системной переменной FLAGS на время вызова подпрограммы CHAN_OPEN (1601Н = 5633 DEC).
На этом мы заканчиваем обзор ошибок и неточностей в ПЗУ стандартного компьютера «ZX Spectrum». Конечно же это не все из того, что оттуда можно выудить, но очень экзотические ошибки, которые проявляются например только на машинах типа «ZX Spectrum+2» и только при подключенном Интерфейсе 1 мы не рассматриваем, поскольку вероятность встретить среди миллионов наших пользователей подобную конфигурацию конечно есть, но она не более сотой доли процента.
Обзор подготовлен по материалам зарубежной печати; основные первоисточники:
1. Dr. Yan Logan, Dr. Frank O’Hara. «The Complete Spectrum ROM Disassembly».
2. Dr. FranK O’Hara «Understanding Your Spectrum».
3. Dr. Yan Logan «Understanding Your Spectrum».
4. Andrew Pennell «Master Your ZX Microdrive».
5. Tony Stratton «Understanding Your Spectrum».
6. Paul Harrison «Understanding Your Spectrum».
7. Stephen Kelly & others «Understanding Your Spectrum».
8. Chris Thornton «Understanding Your Spectrum».
Источник
Почему калькулятор неправильно считает
Тока не смейтесь. 😳
В магазине Комус куплен калькулятор Casio на фирму. Так вот, эта падла неправильно считает проценты. :kto: Обнаружено случайно — бухгалтера сделали мне замечание, мол, ты чо? Хорошо, что сейчас всплыло, а не через год работы этим калькулятором :!a:
А именно: «100» «+» «20» «%» (если набрать такую комбинацию) должно получиться 120. Он выдаёт 125.
Иду в Комус, продавец в лёкгом шоке. :tik Проверили на калькуляторе другой фирмы — там всё чётко. Забрали на эксперитизу.
Умные люди надоумили слупить с Casio лимон баксов — мол, из-за неправильных подсчётов денег ( а что ещё считать на калькуляторе?) на вашем грёбаном калькуляторе потерперпел убытки. Плюс скандал.
Чо думаете? Звонил Саше НМХ — на звонок не ответил. #-o
Дубликаты не найдены
А я в гугле проверил
можно ещё 12345679*8
Так-то сейчас актуально стало с учетом распространения программ калькуляторов на плэймаркете от разных багоделов.
Комментарий дня
Получается, что белые — это негры с нарушенной пигментацией?)
Калькуляторы сегодня встраиваются буквально во все: в часы, телефоны, смартфоны, плееры и прочие электронные устройства. Однако калькулятор, как самостоятельное устройство будет востребован еще очень долго.
Он необходим школьникам и студентам, домохозяйкам и бухгалтерам, инженерам и менеджерам.
Купить калькулятор, подходящий именно вам, несложно, нужно только четко знать, какой именно калькулятор нужен.
Существуют разные типы подобных устройств:
Обычный (простейший) с минимальным набором функций. Подойдет для школьников и для тех, кто выполняет обычно несложные вычисления.
Бухгалтерский – как правило, настольный с крупными кнопками. Имеет специальные «денежные» кнопки, автоматическое округление и т. п.
Банковский (финансовый) – предназначен для подсчета процентов и других специфических операций.
Инженерный и программируемый калькулятор имеют множество функций и позволяют производить сложные вычисления. Имеют возможность программирования пользователем.
Разумеется, калькулятор должен иметь прочный корпус, емкую батарею, достаточное количество разрядов на дисплее. Но главное в работе любого вычислительного устройства – точность и надежность.
Как проверить калькулятор?
Существует несколько несложных способов, позволяющих выяснить, не «врет» ли устройство. Прежде всего: попробуйте перемножить или сложить максимально большие числа.
Если калькулятор не выдаст сообщение об ошибке и не сломается – отлично, самый первый тест пройден.
Задайте несколько примеров на сложение, несложных, типа: 3+6=9. Затем сложнее: 1111х1111=1234321.
Почему именно такой пример? А его запомнить просто! Или еще: 11111х11111=123454321. Есть пример на вычитание: 12345678-123456789=-111111111.
Существуют и другие формулы проверки, которые ничем не отличаются от любых других, кроме того, что легко запоминаются:
- 12345679х9=111111111
- 123123123 : 1001001=123
- 12345679х8=98765432
А вот еще один интересный способ — 12345679*7,2 получится 88888888888 то есть все восьмёрки, сразу видно, что логика не сбита и дисплей весь рабочий!
Проверка калькулятора не займет много времени. Однако если калькулятор нужен для проведения инженерных расчетов, применения функций и т. п., то и проверять нужно именно их. Еще по теме:
Источник
Подсчитаем баги в калькуляторе Windows
Введение
Калькулятор Windows наверняка знаком каждому пользователю этой операционной системы и не требует особого представления. Теперь же любой пользователь может изучить исходный код калькулятора на GitHub и предложить свои улучшения.
Общественность, например, уже обратила внимание на такую функцию:
которая логирует текст из буфера обмена и, возможно, отправляет его на серверы Microsoft. Но эта заметка не об этом. Хотя подозрительных примеров кода будет много.
Мы проверили исходный код калькулятора с помощью статического анализатора PVS-Studio. Так как код написан на нестандартном C++, многие постоянные читатели блога анализатора усомнились в возможности анализа, но это оказалось возможным. C++/CLI и C++/CX поддерживаются анализатором. Некоторые диагностики выдали ложные предупреждения из-за этого, но ничего критичного не произошло, что помешало бы воспользоваться этим инструментом.
Возможно, вы пропустили новости и о других возможностях PVS-Studio, поэтому хочу напомнить, что кроме проектов на языках C и C++, можно проанализировать код и на языках C# и Java.
Про неправильное сравнение строк
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. CalcManager UnitConverter.cpp 778
Избыточность
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
Источник














