/
aserger
/
cutcalcut
Обзор
Документация
Войти
/
aserger
/
cutcalcut
Код
Запросы
2
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
Calcul/CalculatorEngine.js
337 строк
11 KB
SergeyParkhachevIP-415
вся логика работает и функционирует
15 дек 2025, 14:57
15 дек 2025, 14:57
5ba915a
Код
Авторство
О чём код?
// CalculatorLogic.js .pragma library // Состояние калькулятора var accumulator = 0 var pendingOperator = "" var lastButton = "" var digits = "" var currentExpression = "" var maxDigits = 12 var memory = 0 // Основные функции function clearAll() { accumulator = 0 pendingOperator = "" lastButton = "" digits = "" currentExpression = "" return getDisplayData() } function isOperationDisabled(op) { // Пустая строка - только цифры и C if (digits === "" && !((op >= "0" && op <= "9") || op === "C" || op === "(" || op === ")")) return true // Удаление - только если есть что удалять if (op === "←" && digits === "") return true // Равно - только если есть операция if (op === "=" && pendingOperator === "") return true // Точка - только если её ещё нет if (op === "." && digits.indexOf(".") !== -1) return true // Корень - только если не отрицательное if (op === "√" && digits.charAt(0) === "-") return true return false } function handleDigit(digit) { if (digit >= "0" && digit <= "9") { // Если только что был результат или операция, сбросить if (lastButton === "=" || ["+", "-", "×", "÷", "/"].includes(lastButton)) { digits = digit } // Если достигнут лимит цифр else if (digits.replace(".", "").length >= maxDigits) { return getDisplayData() } // Иначе добавляем цифру else { digits = (digits === "0") ? digit : digits + digit } lastButton = digit } return getDisplayData() } function handleOperator(op) { // Проверка на отключенные операции if (isOperationDisabled(op)) { return getDisplayData() } switch(op) { case "C": return clearAll() case "←": digits = digits.slice(0, -1) if (digits === "" || digits === "-") digits = "0" lastButton = op break case ".": if (digits.indexOf(".") === -1) { digits += "." } lastButton = op break case "±": if (digits !== "0") { digits = digits.charAt(0) === "-" ? digits.slice(1) : "-" + digits } lastButton = op break case "+": case "-": case "×": case "÷": case "/": // Если уже есть операция, вычисляем сначала if (pendingOperator !== "" && digits !== "") { calculateResult() } if (digits !== "") { accumulator = parseFloat(digits) } pendingOperator = op currentExpression = formatNumber(accumulator) + " " + op digits = "" lastButton = op break case "=": if (pendingOperator !== "" && digits !== "") { // Проверка деления на ноль if (pendingOperator === "/" && parseFloat(digits) === 0) { var errorResult = { display: "0", expression: "", error: "Деление на ноль" } clearAll() return errorResult } // Сохраняем значения ДО вычисления var firstNumber = accumulator var secondNumber = parseFloat(digits) var operation = pendingOperator // Вычисляем calculateResult() // Формируем выражение с сохраненными значениями currentExpression = formatNumber(firstNumber) + " " + operation + " " + formatNumber(secondNumber) + " = " + formatNumber(accumulator) pendingOperator = "" digits = accumulator.toString() lastButton = op } break case "√": if (digits !== "") { var value = parseFloat(digits) if (value >= 0) { digits = Math.sqrt(value).toString() currentExpression = "√(" + formatNumber(value) + ") = " + formatNumber(parseFloat(digits)) } else { // Ошибка: корень из отрицательного return { display: digits, expression: currentExpression, error: "Корень из отрицательного числа" } } lastButton = op } break case "x²": if (digits !== "") { var value = parseFloat(digits) digits = (value * value).toString() currentExpression = "(" + formatNumber(value) + ")² = " + formatNumber(parseFloat(digits)) lastButton = op } break case "%": if (digits !== "") { var value = parseFloat(digits) digits = (value / 100).toString() currentExpression = formatNumber(value) + "% = " + formatNumber(parseFloat(digits)) lastButton = op } break case "!": if (digits !== "") { var value = parseInt(digits) if (value >= 0 && value <= 20) { var fact = 1 for (var i = 2; i <= value; i++) { fact *= i } digits = fact.toString() currentExpression = value + "! = " + formatNumber(fact) } else { return { display: digits, expression: currentExpression, error: "Факториал: 0-20" } } lastButton = op } break } return getDisplayData() } function calculateResult() { if (pendingOperator === "" || digits === "") return var current = parseFloat(digits) switch(pendingOperator) { case "+": accumulator = accumulator + current break case "-": accumulator = accumulator - current break case "×": case "*": accumulator = accumulator * current break case "÷": case "/": if (current === 0) { return { display: digits, expression: currentExpression, error: "Деление на ноль" } } accumulator = accumulator / current break } digits = accumulator.toString() } function getDisplayData() { return { display: formatNumber(digits === "" ? "0" : digits), expression: currentExpression, error: "" } } function formatNumber(numStr) { var num = parseFloat(numStr) if (isNaN(num)) return "0" // Если число целое и маленькое if (Number.isInteger(num) && Math.abs(num) < 1e12) { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ") } var str = num.toString() // Определяем, нужно ли использовать экспоненциальную запись var useExponential = false // Используем экспоненциальную только для очень больших/маленьких чисел if (Math.abs(num) >= 1e12 || (Math.abs(num) > 0 && Math.abs(num) < 1e-6)) { useExponential = true } // Или если строка слишком длинная else if (str.length > maxDigits) { // Проверяем, есть ли много нулей после точки if (str.indexOf('.') !== -1) { var decimalPart = str.split('.')[1] // Если много цифр после точки, используем округление if (decimalPart && decimalPart.length > 8) { // Округляем до 8 знаков после запятой num = Math.round(num * 1e8) / 1e8 str = num.toString() // Если после округления всё ещё длинно, используем экспоненциальную if (str.length > maxDigits) { useExponential = true } } } else { useExponential = true } } if (useExponential) { // Для экспоненциальной записи используем 8 знаков после запятой return num.toExponential(8).replace('e', 'e').replace('+', '') } // Убираем лишние нули после точки if (str.indexOf('.') !== -1) { // Убираем конечные нули str = str.replace(/(\.[0-9]*?)0+$/, '$1') // Убираем точку, если после неё ничего нет if (str.endsWith('.')) { str = str.slice(0, -1) } // Ограничиваем количество знаков после запятой var parts = str.split('.') if (parts[1] && parts[1].length > 8) { parts[1] = parts[1].substring(0, 8) // Убираем конечные нули после обрезки parts[1] = parts[1].replace(/0+$/, '') str = parts[0] + (parts[1] ? '.' + parts[1] : '') } } // Добавляем разделители тысяч (только для целой части) var parts = str.split('.') if (Math.abs(parseInt(parts[0])) >= 1000) { parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, " ") } return parts.length > 1 ? parts[0] + '.' + parts[1] : parts[0] } // Функции памяти function memoryClear() { memory = 0 } function memoryRecall() { digits = memory.toString() return getDisplayData() } function memoryAdd() { var value = parseFloat(digits || "0") memory += value } function memorySubtract() { var value = parseFloat(digits || "0") memory -= value }