Add .config/DankMaterialShell/plugin_settings.json Add .config/DankMaterialShell/plugins/calculator/CalculatorLauncher.qml Add .config/DankMaterialShell/plugins/calculator/CalculatorSettings.qml Add .config/DankMaterialShell/plugins/calculator/README.md Add .config/DankMaterialShell/plugins/calculator/calculator.js Add .config/DankMaterialShell/plugins/calculator/.git/HEAD Add .config/DankMaterialShell/plugins/calculator/.git/config Add .config/DankMaterialShell/plugins/calculator/.git/index Add .config/DankMaterialShell/plugins/calculator/.git/objects/info/.keep Add .config/DankMaterialShell/plugins/calculator/.git/objects/pack/pack-67f644835e660794f65c9273e46788b0c3da57cf.idx Add .config/DankMaterialShell/plugins/calculator/.git/objects/pack/pack-67f644835e660794f65c9273e46788b0c3da57cf.rev Add .config/DankMaterialShell/plugins/calculator/.git/objects/pack/pack-67f644835e660794f65c9273e46788b0c3da57cf.pack Add .config/DankMaterialShell/plugins/calculator/.git/refs/heads/main Add .config/DankMaterialShell/plugins/calculator/.git/refs/remotes/origin/main Add .config/DankMaterialShell/plugins/calculator/.git/refs/remotes/origin/qalc Add .config/DankMaterialShell/plugins/calculator/.git/refs/tags/.keep Add .config/DankMaterialShell/plugins/calculator/plugin.json Add .config/DankMaterialShell/plugins/calculator/screenshot.png Add .config/DankMaterialShell/plugins/calculator/test_precision.js Add .config/DankMaterialShell/plugins/calculator/test_single.js Add .config/DankMaterialShell/plugins/commandRunner/CommandRunner.qml Add .config/DankMaterialShell/plugins/commandRunner/CommandRunnerSettings.qml Add .config/DankMaterialShell/plugins/commandRunner/LICENSE Add .config/DankMaterialShell/plugins/commandRunner/README.md Add .config/DankMaterialShell/plugins/commandRunner/.git/HEAD Add .config/DankMaterialShell/plugins/commandRunner/.git/config Add .config/DankMaterialShell/plugins/commandRunner/.git/index Add .config/DankMaterialShell/plugins/commandRunner/.git/objects/info/.keep Add .config/DankMaterialShell/plugins/commandRunner/.git/objects/pack/pack-5a720f795fd2994ef506cd867d86ca7df8a25a31.idx Add .config/DankMaterialShell/plugins/commandRunner/.git/objects/pack/pack-5a720f795fd2994ef506cd867d86ca7df8a25a31.rev Add .config/DankMaterialShell/plugins/commandRunner/.git/objects/pack/pack-5a720f795fd2994ef506cd867d86ca7df8a25a31.pack Add .config/DankMaterialShell/plugins/commandRunner/.git/refs/heads/main Add .config/DankMaterialShell/plugins/commandRunner/.git/refs/remotes/origin/main Add .config/DankMaterialShell/plugins/commandRunner/.git/refs/tags/.keep Add .config/DankMaterialShell/plugins/commandRunner/plugin.json Add .config/DankMaterialShell/plugins/commandRunner/screenshot.png Add .config/DankMaterialShell/plugins/dankActions.meta Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankActions/DankActionsSettings.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankActions/DankActionsWidget.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankActions/plugin.json Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankBatteryAlerts/DankBatteryAlerts.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankBatteryAlerts/DankBatteryAlertsSettings.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankBatteryAlerts/plugin.json Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankHooks/DankHooks.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankHooks/DankHooksSettings.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankHooks/README.md Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankHooks/plugin.json Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankPomodoroTimer/DankPomodoroSettings.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankPomodoroTimer/DankPomodoroWidget.qml Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/DankPomodoroTimer/plugin.json Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/LICENSE Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/README.md Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/HEAD Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/config Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/index Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/objects/info/.keep Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/objects/pack/pack-3221a15c022ef4a7bb6bf2c47e40068b66b3588b.idx Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/objects/pack/pack-3221a15c022ef4a7bb6bf2c47e40068b66b3588b.rev Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/objects/pack/pack-3221a15c022ef4a7bb6bf2c47e40068b66b3588b.pack Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/refs/heads/master Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/refs/remotes/origin/master Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.git/refs/tags/.keep Add .config/DankMaterialShell/plugins/.repos/0026f1eba8dedaec/.gitignore Add .config/DankMaterialShell/plugins/emojiLauncher/EmojiLauncher.qml Add .config/DankMaterialShell/plugins/emojiLauncher/EmojiLauncherSettings.qml Add .config/DankMaterialShell/plugins/emojiLauncher/LICENSE Add .config/DankMaterialShell/plugins/emojiLauncher/README.md Add .config/DankMaterialShell/plugins/emojiLauncher/catalog.js Add .config/DankMaterialShell/plugins/emojiLauncher/data/emojis.txt Add .config/DankMaterialShell/plugins/emojiLauncher/data/math.txt Add .config/DankMaterialShell/plugins/emojiLauncher/data/nerdfont.txt Add .config/DankMaterialShell/plugins/emojiLauncher/.git/HEAD Add .config/DankMaterialShell/plugins/emojiLauncher/.git/config Add .config/DankMaterialShell/plugins/emojiLauncher/.git/index Add .config/DankMaterialShell/plugins/emojiLauncher/.git/objects/info/.keep Add .config/DankMaterialShell/plugins/emojiLauncher/.git/objects/pack/pack-e04a5b1ea381dc3a792b8bf08cf70e735b195c0d.idx Add .config/DankMaterialShell/plugins/emojiLauncher/.git/objects/pack/pack-e04a5b1ea381dc3a792b8bf08cf70e735b195c0d.rev Add .config/DankMaterialShell/plugins/emojiLauncher/.git/objects/pack/pack-e04a5b1ea381dc3a792b8bf08cf70e735b195c0d.pack Add .config/DankMaterialShell/plugins/emojiLauncher/.git/refs/heads/main Add .config/DankMaterialShell/plugins/emojiLauncher/.git/refs/remotes/origin/main Add .config/DankMaterialShell/plugins/emojiLauncher/.git/refs/tags/.keep Add .config/DankMaterialShell/plugins/emojiLauncher/plugin.json Add .config/DankMaterialShell/plugins/emojiLauncher/screenshot.png Add .config/DankMaterialShell/plugins/emojiLauncher/scripts/generate_catalog.py Add .config/DankMaterialShell/plugins/dankActions Add .config/DankMaterialShell/plugins/webSearch/LICENSE Add .config/DankMaterialShell/plugins/webSearch/README.md Add .config/DankMaterialShell/plugins/webSearch/WebSearch.qml Add .config/DankMaterialShell/plugins/webSearch/WebSearchSettings.qml Add .config/DankMaterialShell/plugins/webSearch/.git/HEAD Add .config/DankMaterialShell/plugins/webSearch/.git/config Add .config/DankMaterialShell/plugins/webSearch/.git/index Add .config/DankMaterialShell/plugins/webSearch/.git/objects/info/.keep Add .config/DankMaterialShell/plugins/webSearch/.git/objects/pack/pack-6a60c736f418e5b4b1f0505f66c1e2a371d46fed.idx Add .config/DankMaterialShell/plugins/webSearch/.git/objects/pack/pack-6a60c736f418e5b4b1f0505f66c1e2a371d46fed.rev Add .config/DankMaterialShell/plugins/webSearch/.git/objects/pack/pack-6a60c736f418e5b4b1f0505f66c1e2a371d46fed.pack Add .config/DankMaterialShell/plugins/webSearch/.git/refs/heads/main Add .config/DankMaterialShell/plugins/webSearch/.git/refs/remotes/origin/main Add .config/DankMaterialShell/plugins/webSearch/.git/refs/tags/.keep Add .config/DankMaterialShell/plugins/webSearch/plugin.json Add .config/DankMaterialShell/plugins/webSearch/screenshot.png Add .config/DankMaterialShell/settings.json
181 lines
6.2 KiB
JavaScript
181 lines
6.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
// Test cases for calculator precision improvements
|
|
// Note: This is a Node.js test file for demonstration purposes
|
|
// The actual calculator.js is a QML JavaScript module
|
|
|
|
// Mock QML .pragma library behavior
|
|
const Calculator = {
|
|
isIntegerOnly: function(expression) {
|
|
return !/\./.test(expression);
|
|
},
|
|
|
|
evaluateInteger: function(expression) {
|
|
try {
|
|
let expr = expression.replace(/\s/g, '');
|
|
|
|
if (expr.includes('^') || expr.includes('/')) {
|
|
return null;
|
|
}
|
|
|
|
expr = expr.replace(/(\d+)/g, '$1n');
|
|
const result = eval(expr);
|
|
const numResult = Number(result);
|
|
|
|
if (Number.isSafeInteger(numResult)) {
|
|
return numResult;
|
|
}
|
|
|
|
return result.toString().replace(/n$/, '');
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
},
|
|
|
|
evaluatePrecise: function(expression) {
|
|
try {
|
|
let cleaned = expression.replace(/\^/g, '**');
|
|
let result = eval(cleaned);
|
|
|
|
if (typeof result !== 'number' || !isFinite(result)) {
|
|
return null;
|
|
}
|
|
|
|
if (Math.abs(result) < 1e-10 && result !== 0) {
|
|
return result;
|
|
}
|
|
|
|
if (result % 1 !== 0) {
|
|
const resultStr = result.toString();
|
|
if (resultStr.includes('e')) {
|
|
return result;
|
|
}
|
|
|
|
const precision = 15;
|
|
const rounded = parseFloat(result.toPrecision(precision));
|
|
|
|
if (rounded % 1 === 0 && Math.abs(rounded) < Number.MAX_SAFE_INTEGER) {
|
|
return Math.round(rounded);
|
|
}
|
|
|
|
return rounded;
|
|
}
|
|
|
|
return result;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
},
|
|
|
|
evaluate: function(expression) {
|
|
if (!expression || typeof expression !== 'string') {
|
|
return { success: false, result: null, error: "Invalid expression" };
|
|
}
|
|
|
|
let cleaned = expression.trim();
|
|
|
|
if (cleaned.length === 0) {
|
|
return { success: false, result: null, error: "Empty expression" };
|
|
}
|
|
|
|
const allowedChars = /^[0-9+\-*/().\s%^]+$/;
|
|
if (!allowedChars.test(cleaned)) {
|
|
return { success: false, result: null, error: "Invalid characters" };
|
|
}
|
|
|
|
const hasOperator = /[+\-*/^%]/.test(cleaned);
|
|
const isSimpleNumber = /^-?\d+\.?\d*$/.test(cleaned);
|
|
|
|
if (!hasOperator && !isSimpleNumber) {
|
|
return { success: false, result: null, error: "Not a math expression" };
|
|
}
|
|
|
|
try {
|
|
let result;
|
|
|
|
if (this.isIntegerOnly(cleaned) && !cleaned.includes('/')) {
|
|
result = this.evaluateInteger(cleaned);
|
|
}
|
|
|
|
if (result === null || result === undefined) {
|
|
result = this.evaluatePrecise(cleaned);
|
|
}
|
|
|
|
if (result === null || result === undefined) {
|
|
return { success: false, result: null, error: "Evaluation failed" };
|
|
}
|
|
|
|
if (typeof result === 'number' && !isFinite(result)) {
|
|
return { success: false, result: null, error: "Invalid result" };
|
|
}
|
|
|
|
return { success: true, result: result, error: null };
|
|
} catch (e) {
|
|
return { success: false, result: null, error: "Evaluation error: " + e.message };
|
|
}
|
|
}
|
|
};
|
|
|
|
// Test cases
|
|
console.log("=== Calculator Precision Test Suite ===\n");
|
|
|
|
const tests = [
|
|
// Floating point precision tests
|
|
{ expr: "0.1 + 0.2", expected: "0.3", description: "Classic floating point precision issue" },
|
|
{ expr: "0.1 + 0.2 + 0.3", expected: "0.6", description: "Multiple decimal additions" },
|
|
{ expr: "1.1 + 2.2", expected: "3.3", description: "Simple decimal addition" },
|
|
{ expr: "3.3 - 1.1", expected: "2.2", description: "Decimal subtraction" },
|
|
{ expr: "0.3 - 0.1", expected: "0.2", description: "Another precision issue" },
|
|
|
|
// BigInt large integer tests
|
|
{ expr: "999999999999999999 + 1", expected: "1000000000000000000", description: "Large integer addition (BigInt)" },
|
|
{ expr: "123456789012345678 * 2", expected: "246913578024691356", description: "Large integer multiplication (BigInt)" },
|
|
{ expr: "999999999999999999 - 999999999999999998", expected: "1", description: "Large integer subtraction" },
|
|
|
|
// Regular operations
|
|
{ expr: "2 + 2", expected: "4", description: "Simple addition" },
|
|
{ expr: "10 - 3", expected: "7", description: "Simple subtraction" },
|
|
{ expr: "5 * 6", expected: "30", description: "Simple multiplication" },
|
|
{ expr: "20 / 4", expected: "5", description: "Simple division" },
|
|
{ expr: "2 ^ 10", expected: "1024", description: "Exponentiation" },
|
|
{ expr: "17 % 5", expected: "2", description: "Modulo" },
|
|
{ expr: "(5 + 3) * 2", expected: "16", description: "Parentheses" },
|
|
|
|
// Edge cases
|
|
{ expr: "100 / 3", expected: "33.3333333333333", description: "Repeating decimal (rounded to 15 sig figs)" },
|
|
{ expr: "1.23456789012345678", expected: "1.23456789012346", description: "High precision decimal (rounded to 15 sig figs)" }
|
|
];
|
|
|
|
let passed = 0;
|
|
let failed = 0;
|
|
|
|
tests.forEach((test, index) => {
|
|
const result = Calculator.evaluate(test.expr);
|
|
const resultStr = result.success ? result.result.toString() : "ERROR";
|
|
const matches = resultStr.startsWith(test.expected.substring(0, Math.min(test.expected.length, 10)));
|
|
|
|
if (matches) {
|
|
console.log(`✓ Test ${index + 1}: ${test.description}`);
|
|
console.log(` Expression: ${test.expr}`);
|
|
console.log(` Result: ${resultStr}`);
|
|
passed++;
|
|
} else {
|
|
console.log(`✗ Test ${index + 1}: ${test.description}`);
|
|
console.log(` Expression: ${test.expr}`);
|
|
console.log(` Expected: ${test.expected}`);
|
|
console.log(` Got: ${resultStr}`);
|
|
failed++;
|
|
}
|
|
console.log();
|
|
});
|
|
|
|
console.log(`=== Test Results ===`);
|
|
console.log(`Passed: ${passed}/${tests.length}`);
|
|
console.log(`Failed: ${failed}/${tests.length}`);
|
|
|
|
if (failed === 0) {
|
|
console.log("\n✓ All tests passed!");
|
|
} else {
|
|
console.log(`\n✗ ${failed} test(s) failed`);
|
|
process.exit(1);
|
|
}
|