Compare commits
11 Commits
4bb7633353
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| cd8ba1c8aa | |||
| 7f5d6f6bed | |||
| b36f541ce3 | |||
| 1a94116975 | |||
| ecbf7f0f8a | |||
| 41c38055a1 | |||
| cb230638bd | |||
| 0571bc1741 | |||
| fd4126b8af | |||
| 35b257dd61 | |||
| 159f4197ae |
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,57 @@
|
||||
# numnum
|
||||
# NumNum
|
||||
|
||||
тренер систем счисления
|
||||
Numeral systems trainer PWA
|
||||
|
||||
**Demo:** [numnum.atroshin.ru](https://numnum.atroshin.ru)
|
||||
|
||||
## Features
|
||||
|
||||
- 10 numeral systems: Binary, Ternary, Balanced Ternary, Octal, Hexadecimal, Braille Decimal, Roman, Church Slavonic, Greek, Hebrew
|
||||
- Two game modes: multiple choice and manual entry (numpad)
|
||||
- Configurable number range, time limit (1s–30s or no limit), question count (5–100)
|
||||
- Installable PWA with full offline support (theory content cached)
|
||||
- Dark/light theme · Bilingual (English / Русский)
|
||||
- In-app theory reference for each system
|
||||
|
||||
## Usage
|
||||
|
||||
Serve the directory with any HTTP server:
|
||||
|
||||
```
|
||||
python3 -m http.server 8080
|
||||
```
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
index.html — Entry point
|
||||
app.js — Game logic and UI
|
||||
numerals.js — Numeral system converters and choice generator
|
||||
styles.css — Styles, dark/light theme
|
||||
sw.js — Service worker (PWA caching)
|
||||
manifest.json — PWA manifest
|
||||
theory/ — Theory HTML files (10 systems × 2 languages)
|
||||
```
|
||||
|
||||
## Supported systems
|
||||
|
||||
| System | Type | Range |
|
||||
|---|---|---|
|
||||
| Binary | Positional | 1–32768 |
|
||||
| Ternary | Positional | 1–27 |
|
||||
| Balanced Ternary | Positional | –27–27 |
|
||||
| Octal | Positional | 1–4096 |
|
||||
| Hexadecimal | Positional | 1–65536 |
|
||||
| Braille Decimal | Positional | 0–9999 |
|
||||
| Roman | Non-positional | 1–3999 |
|
||||
| Church Slavonic | Non-positional | 1–9999 |
|
||||
| Greek | Non-positional | 1–9999 |
|
||||
| Hebrew | Non-positional | 1–9999 |
|
||||
|
||||
## Development
|
||||
|
||||
Theory HTML files live in `theory/`. After editing them, bump the version in `sw.js` to refresh the cache on next install.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
@@ -6,6 +6,7 @@ const STRINGS = {
|
||||
en: {
|
||||
subtitle: 'Numeral systems trainer',
|
||||
startGame: 'Start',
|
||||
theory: 'Theory',
|
||||
chooseSystem: 'Choose numeral system',
|
||||
positional: 'Positional',
|
||||
nonPositional: 'Non-Positional',
|
||||
@@ -33,6 +34,7 @@ const STRINGS = {
|
||||
congratulations: 'Congratulations!',
|
||||
pleaseSelect: 'Please select all options',
|
||||
installApp: 'Install App',
|
||||
theoryUnavailable: 'Content unavailable',
|
||||
sec: 'sec',
|
||||
chooseAnswer: 'Choose answer',
|
||||
enterEquivalent: 'Enter equivalent',
|
||||
@@ -46,6 +48,7 @@ const STRINGS = {
|
||||
ru: {
|
||||
subtitle: '\u0422\u0440\u0435\u043D\u0430\u0436\u0435\u0440 \u0441\u0438\u0441\u0442\u0435\u043C \u0441\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F',
|
||||
startGame: 'Начать',
|
||||
theory: '\u0422\u0435\u043E\u0440\u0438\u044F',
|
||||
chooseSystem: '\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0441\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F',
|
||||
positional: '\u041F\u043E\u0437\u0438\u0446\u0438\u043E\u043D\u043D\u044B\u0435',
|
||||
nonPositional: '\u041D\u0435\u043F\u043E\u0437\u0438\u0446\u0438\u043E\u043D\u043D\u044B\u0435',
|
||||
@@ -73,6 +76,7 @@ const STRINGS = {
|
||||
congratulations: '\u041F\u043E\u0437\u0434\u0440\u0430\u0432\u043B\u044F\u0435\u043C!',
|
||||
pleaseSelect: '\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0441\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B',
|
||||
installApp: '\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435',
|
||||
theoryUnavailable: '\u041C\u0430\u0442\u0435\u0440\u0438\u0430\u043B \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D',
|
||||
sec: '\u0441\u0435\u043A',
|
||||
chooseAnswer: '\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0442\u0432\u0435\u0442',
|
||||
enterEquivalent: '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043B\u043E',
|
||||
@@ -111,6 +115,55 @@ function applyTranslations() {
|
||||
});
|
||||
}
|
||||
|
||||
function refreshDynamicText() {
|
||||
const active = document.querySelector('.screen.active');
|
||||
if (!active) return;
|
||||
switch (active.id) {
|
||||
case 'screen-setup-system':
|
||||
renderSetupSystem();
|
||||
break;
|
||||
case 'screen-setup-range':
|
||||
renderSetupRange();
|
||||
break;
|
||||
case 'screen-setup-options':
|
||||
document.querySelectorAll('#setup-modes .option-btn').forEach((btn, i) => {
|
||||
btn.textContent = t(MODES[i].labelKey);
|
||||
});
|
||||
[...document.getElementById('setup-timing').options].forEach((opt, i) => {
|
||||
opt.textContent = TIMINGS[i].value === 0 ? t('noLimit') : TIMINGS[i].value + ' ' + t('sec');
|
||||
});
|
||||
break;
|
||||
case 'screen-theory-system':
|
||||
renderTheorySystem();
|
||||
break;
|
||||
case 'screen-theory-content':
|
||||
document.getElementById('theory-title').textContent = systemName(lastTheoryKey);
|
||||
break;
|
||||
case 'screen-game':
|
||||
if (game.system && game.range) {
|
||||
document.getElementById('score-system-range').textContent = systemName(game.system) + ': ' + game.range.label;
|
||||
}
|
||||
break;
|
||||
case 'screen-results': {
|
||||
const completed = game.currentRound >= game.rounds;
|
||||
const total = completed ? game.rounds : game.currentRound;
|
||||
const pct = total > 0 ? Math.round((game.correctCount / total) * 100) : 0;
|
||||
document.getElementById('results-summary').innerHTML =
|
||||
'<div class="big-number">' + game.correctCount + '/' + total + '</div>' +
|
||||
'<div>' + t('pctCorrect', {pct: pct}) + '</div>';
|
||||
const labelEl = document.getElementById('results-mistakes-label');
|
||||
if (game.mistakes.length > 0 || labelEl.style.display !== 'none') {
|
||||
labelEl.textContent = t('mistakes');
|
||||
}
|
||||
const congratsEl = document.getElementById('results-congrats');
|
||||
if (congratsEl.textContent) {
|
||||
congratsEl.textContent = t('congratulations');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SYSTEM_RANGES = {
|
||||
binary: [
|
||||
{ label: '2\u2070 \u2013 2\u00B3', min: 1, max: 8 },
|
||||
@@ -185,6 +238,9 @@ const SYSTEM_GROUPS = {
|
||||
nonpos: ['roman', 'greek', 'slavonic', 'hebrew'],
|
||||
};
|
||||
|
||||
const theoryCache = {};
|
||||
let lastTheoryKey = null;
|
||||
|
||||
const MODES = [
|
||||
{ labelKey: 'choose', value: 'choice' },
|
||||
{ labelKey: 'type', value: 'manual' },
|
||||
@@ -217,9 +273,23 @@ let game = {
|
||||
mistakes: [],
|
||||
};
|
||||
|
||||
let popstateHandled = false;
|
||||
let navDepth = 0;
|
||||
|
||||
function showScreen(id) {
|
||||
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
|
||||
document.getElementById('screen-' + id).classList.add('active');
|
||||
if (id === 'menu') {
|
||||
if (navDepth > 0) {
|
||||
const n = navDepth;
|
||||
navDepth = 0;
|
||||
history.go(-n);
|
||||
}
|
||||
} else if (!popstateHandled) {
|
||||
navDepth++;
|
||||
history.pushState({ screen: id }, '');
|
||||
}
|
||||
popstateHandled = false;
|
||||
}
|
||||
|
||||
function shuffle(arr) {
|
||||
@@ -344,7 +414,7 @@ const MARK_INCORRECT = '\u2717 ';
|
||||
function startGame() {
|
||||
lastSetupState = { ...setupState };
|
||||
game.system = setupState.system;
|
||||
game.range = setupState.rangeData || RANGES[setupState.range];
|
||||
game.range = setupState.rangeData;
|
||||
game.mode = MODES[setupState.mode]?.value ?? setupState.mode;
|
||||
game.timing = TIMINGS[setupState.timing]?.value ?? setupState.timing;
|
||||
game.rounds = ROUNDS[setupState.rounds];
|
||||
@@ -700,6 +770,58 @@ function spawnConfetti() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---- THEORY ----
|
||||
|
||||
async function loadTheory(key) {
|
||||
if (theoryCache[key]) return theoryCache[key];
|
||||
try {
|
||||
const resp = await fetch(`theory/${key}.${LANG}.html`);
|
||||
if (!resp.ok) throw new Error(resp.status);
|
||||
const html = await resp.text();
|
||||
theoryCache[key] = html;
|
||||
return html;
|
||||
} catch {
|
||||
if (LANG !== 'en') {
|
||||
try {
|
||||
const resp = await fetch(`theory/${key}.en.html`);
|
||||
const html = await resp.text();
|
||||
theoryCache[key] = html;
|
||||
return html;
|
||||
} catch { return null; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function renderTheorySystem() {
|
||||
const posDiv = document.getElementById('theory-systems-pos');
|
||||
const nonposDiv = document.getElementById('theory-systems-nonpos');
|
||||
posDiv.innerHTML = '';
|
||||
nonposDiv.innerHTML = '';
|
||||
|
||||
for (const [group, keys] of Object.entries(SYSTEM_GROUPS)) {
|
||||
const target = group === 'pos' ? posDiv : nonposDiv;
|
||||
keys.forEach(key => {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'option-btn';
|
||||
btn.textContent = systemName(key);
|
||||
btn.addEventListener('click', () => showTheoryContent(key));
|
||||
target.appendChild(btn);
|
||||
});
|
||||
}
|
||||
|
||||
showScreen('theory-system');
|
||||
}
|
||||
|
||||
async function showTheoryContent(key) {
|
||||
lastTheoryKey = key;
|
||||
const html = await loadTheory(key);
|
||||
document.getElementById('theory-title').textContent = systemName(key);
|
||||
document.getElementById('theory-scroll').innerHTML =
|
||||
html || '<div class="theory-unavailable">' + t('theoryUnavailable') + '</div>';
|
||||
showScreen('theory-content');
|
||||
}
|
||||
|
||||
// ---- INIT ----
|
||||
|
||||
const SUBSCRIPTS = { '0':'\u2080', '1':'\u2081', '2':'\u2082', '3':'\u2083',
|
||||
@@ -727,9 +849,6 @@ function getPreferredTheme() {
|
||||
return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
}
|
||||
|
||||
const isLightTheme = getPreferredTheme() === 'light';
|
||||
const TICKER_COLORS = isLightTheme ? TICKER_COLORS_LIGHT : TICKER_COLORS_DARK;
|
||||
|
||||
const TICKER_SYSTEMS = [
|
||||
{ key: 'binary', min: 1, max: 255, suffix: toSubscript(2) },
|
||||
{ key: 'base3', min: 1, max: 81, suffix: toSubscript(3) },
|
||||
@@ -743,6 +862,9 @@ const TICKER_SYSTEMS = [
|
||||
];
|
||||
|
||||
function generateTickerText() {
|
||||
const palette = document.documentElement.dataset.theme === 'light'
|
||||
? TICKER_COLORS_LIGHT
|
||||
: TICKER_COLORS_DARK;
|
||||
const pairs = [];
|
||||
let lastKey = null;
|
||||
let lastColor = null;
|
||||
@@ -755,7 +877,7 @@ function generateTickerText() {
|
||||
|
||||
let color;
|
||||
do {
|
||||
color = TICKER_COLORS[Math.floor(Math.random() * TICKER_COLORS.length)];
|
||||
color = palette[Math.floor(Math.random() * palette.length)];
|
||||
} while (color === lastColor);
|
||||
lastColor = color;
|
||||
const num = sys.min + Math.floor(Math.random() * (sys.max - sys.min + 1));
|
||||
@@ -771,8 +893,10 @@ function generateTickerText() {
|
||||
return pairs.join('\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0');
|
||||
}
|
||||
|
||||
const tickerText = generateTickerText();
|
||||
document.getElementById('ticker').innerHTML = tickerText + '\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0' + tickerText;
|
||||
function refreshTicker() {
|
||||
const tickerText = generateTickerText();
|
||||
document.getElementById('ticker').innerHTML = tickerText + '\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0' + tickerText;
|
||||
}
|
||||
|
||||
const langSelect = document.getElementById('lang-select');
|
||||
langSelect.value = LANG;
|
||||
@@ -780,6 +904,7 @@ langSelect.addEventListener('change', () => {
|
||||
LANG = langSelect.value;
|
||||
localStorage.setItem('numnum-lang', LANG);
|
||||
applyTranslations();
|
||||
refreshDynamicText();
|
||||
});
|
||||
|
||||
applyTranslations();
|
||||
@@ -787,6 +912,7 @@ applyTranslations();
|
||||
function applyTheme(theme) {
|
||||
document.documentElement.dataset.theme = theme;
|
||||
document.getElementById('theme-toggle').textContent = theme === 'dark' ? '\u2600' : '\u263E';
|
||||
refreshTicker();
|
||||
}
|
||||
|
||||
applyTheme(getPreferredTheme());
|
||||
@@ -855,7 +981,8 @@ document.getElementById('btn-options-back').addEventListener('click', () => {
|
||||
});
|
||||
|
||||
document.getElementById('btn-play').addEventListener('click', () => {
|
||||
if (setupState.mode === undefined || setupState.timing === undefined || setupState.rounds === undefined) {
|
||||
if (!setupState.system || !setupState.rangeData ||
|
||||
setupState.mode === undefined || setupState.timing === undefined || setupState.rounds === undefined) {
|
||||
showSetupMessage(t('pleaseSelect'));
|
||||
return;
|
||||
}
|
||||
@@ -875,6 +1002,18 @@ document.getElementById('btn-results-menu').addEventListener('click', () => {
|
||||
showScreen('menu');
|
||||
});
|
||||
|
||||
document.getElementById('btn-theory').addEventListener('click', () => {
|
||||
renderTheorySystem();
|
||||
});
|
||||
|
||||
document.getElementById('btn-theory-back').addEventListener('click', () => {
|
||||
showScreen('menu');
|
||||
});
|
||||
|
||||
document.getElementById('btn-theory-content-back').addEventListener('click', () => {
|
||||
renderTheorySystem();
|
||||
});
|
||||
|
||||
document.getElementById('btn-stop').addEventListener('click', () => {
|
||||
stopTimer();
|
||||
endGame();
|
||||
@@ -909,3 +1048,26 @@ document.addEventListener('keydown', (e) => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle mobile back/cancel button
|
||||
const BACK_MAP = {
|
||||
'screen-setup-system': 'btn-system-back',
|
||||
'screen-setup-range': 'btn-range-back',
|
||||
'screen-setup-options': 'btn-options-back',
|
||||
'screen-game': 'btn-stop',
|
||||
'screen-results': 'btn-results-menu',
|
||||
'screen-theory-system': 'btn-theory-back',
|
||||
'screen-theory-content': 'btn-theory-content-back',
|
||||
};
|
||||
|
||||
window.addEventListener('popstate', () => {
|
||||
navDepth = Math.max(0, navDepth - 1);
|
||||
const active = document.querySelector('.screen.active');
|
||||
if (!active) return;
|
||||
|
||||
const btnId = BACK_MAP[active.id];
|
||||
if (btnId) {
|
||||
popstateHandled = true;
|
||||
document.getElementById(btnId).click();
|
||||
}
|
||||
});
|
||||
|
||||
+29
-3
@@ -10,7 +10,7 @@
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="icon" type="image/svg+xml" href="icon.svg">
|
||||
<link rel="apple-touch-icon" href="icon-192.png">
|
||||
<link rel="stylesheet" href="styles.css?v=20">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
@@ -24,6 +24,7 @@
|
||||
<div class="ticker" id="ticker"></div>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-large" id="btn-start" data-i18n="startGame">Start Game</button>
|
||||
<button class="btn btn-secondary btn-large" id="btn-theory" data-i18n="theory">Theory</button>
|
||||
<div class="menu-controls">
|
||||
<select id="lang-select" class="lang-select">
|
||||
<option value="en">English</option>
|
||||
@@ -165,12 +166,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- THEORY: SYSTEM SELECTION -->
|
||||
<div id="screen-theory-system" class="screen">
|
||||
<div class="setup-container">
|
||||
<h2 data-i18n="chooseSystem">Choose numeral system</h2>
|
||||
<div class="system-group">
|
||||
<h3 data-i18n="nonPositional">Non-Positional</h3>
|
||||
<div id="theory-systems-nonpos" class="option-grid"></div>
|
||||
</div>
|
||||
<div class="system-group">
|
||||
<h3 data-i18n="positional">Positional</h3>
|
||||
<div id="theory-systems-pos" class="option-grid"></div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="btn-theory-back" data-i18n="back">Back</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- THEORY: CONTENT -->
|
||||
<div id="screen-theory-content" class="screen">
|
||||
<div class="theory-container">
|
||||
<h2 id="theory-title"></h2>
|
||||
<div class="theory-scroll" id="theory-scroll"></div>
|
||||
<button class="btn btn-secondary" id="btn-theory-content-back" data-i18n="back">Back</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="module" src="app.js?v=20"></script>
|
||||
<script type="module" src="app.js"></script>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js?v=20').catch(() => {});
|
||||
navigator.serviceWorker.register('/sw.js').catch(() => {});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
+93
-3
@@ -73,13 +73,31 @@ html[data-theme="light"] {
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Symbols 2';
|
||||
src: url('NotoSansSymbols2-subset.woff2') format('woff2');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
unicode-range: U+232B, U+23F1, U+2600, U+2713, U+2717, U+2801, U+2803, U+2809-280B, U+2811, U+2813, U+2819-281B, U+283C, U+2B95;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Symbols 2';
|
||||
src: url('NotoSansMath-subset.woff2') format('woff2');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
unicode-range: U+2295-2296, U+263E;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Noto Sans Symbols 2', sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
@@ -189,7 +207,7 @@ body {
|
||||
white-space: nowrap;
|
||||
color: var(--text-dim);
|
||||
font-size: 1.3rem;
|
||||
font-family: monospace;
|
||||
font-family: 'Noto Sans Symbols 2', monospace;
|
||||
animation: ticker-scroll 40s linear infinite;
|
||||
}
|
||||
|
||||
@@ -455,7 +473,7 @@ body {
|
||||
}
|
||||
|
||||
.number-display.mono {
|
||||
font-family: monospace;
|
||||
font-family: 'Noto Sans Symbols 2', monospace;
|
||||
}
|
||||
|
||||
.ticker .slavonic-font {
|
||||
@@ -748,3 +766,75 @@ body {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* THEORY */
|
||||
.theory-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 24px;
|
||||
padding-top: calc(24px + var(--safe-top));
|
||||
padding-bottom: calc(24px + var(--safe-bottom));
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.theory-container h2 {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.theory-scroll {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.theory-scroll h3 {
|
||||
color: var(--accent);
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin: 24px 0 8px;
|
||||
}
|
||||
|
||||
.theory-scroll h3:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.theory-scroll p {
|
||||
line-height: 1.6;
|
||||
margin-bottom: 12px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.theory-scroll .theory-example {
|
||||
background: var(--bg-card);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
font-family: 'Noto Sans Symbols 2', monospace;
|
||||
font-size: 1.1rem;
|
||||
margin: 12px 0;
|
||||
text-align: center;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.theory-unavailable {
|
||||
text-align: center;
|
||||
opacity: 0.65;
|
||||
padding: 24px 0;
|
||||
}
|
||||
|
||||
.theory-scroll .slavonic-font {
|
||||
font-family: 'Ponomar', serif;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
#btn-theory-content-back {
|
||||
flex-shrink: 0;
|
||||
margin-top: 16px;
|
||||
max-width: 320px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const CACHE_NAME = 'numnum-v20';
|
||||
const CACHE_NAME = 'numnum-v28';
|
||||
const ASSETS = [
|
||||
'/',
|
||||
'/index.html',
|
||||
@@ -9,11 +9,42 @@ const ASSETS = [
|
||||
'/icon.svg',
|
||||
'/icon-192.png',
|
||||
'/icon-512.png',
|
||||
'/Ponomar-Regular.woff',
|
||||
'/NotoSansSymbols2-subset.woff2',
|
||||
'/NotoSansMath-subset.woff2',
|
||||
'/theory/base3.en.html',
|
||||
'/theory/base3.ru.html',
|
||||
'/theory/binary.en.html',
|
||||
'/theory/binary.ru.html',
|
||||
'/theory/braille.en.html',
|
||||
'/theory/braille.ru.html',
|
||||
'/theory/greek.en.html',
|
||||
'/theory/greek.ru.html',
|
||||
'/theory/hebrew.en.html',
|
||||
'/theory/hebrew.ru.html',
|
||||
'/theory/hex.en.html',
|
||||
'/theory/hex.ru.html',
|
||||
'/theory/octal.en.html',
|
||||
'/theory/octal.ru.html',
|
||||
'/theory/roman.en.html',
|
||||
'/theory/roman.ru.html',
|
||||
'/theory/slavonic.en.html',
|
||||
'/theory/slavonic.ru.html',
|
||||
'/theory/ternary.en.html',
|
||||
'/theory/ternary.ru.html',
|
||||
];
|
||||
|
||||
self.addEventListener('install', (e) => {
|
||||
e.waitUntil(
|
||||
caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS))
|
||||
caches.open(CACHE_NAME).then(cache =>
|
||||
Promise.allSettled(ASSETS.map(url => cache.add(url)))
|
||||
).then(results => {
|
||||
results.forEach((r, i) => {
|
||||
if (r.status === 'rejected') {
|
||||
console.warn('SW precache failed:', ASSETS[i], r.reason);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Base: 3</h3>
|
||||
<p>The ternary (base-3) numeral system uses three digits: 0, 1, and 2. Each position represents a power of 3.</p>
|
||||
<h3>How it works</h3>
|
||||
<div class="theory-example">112 = 1×9 + 1×3 + 2×1 = 14</div>
|
||||
<h3>Digits</h3>
|
||||
<div class="theory-example">0 1 2</div>
|
||||
<h3>Uses</h3>
|
||||
<p>Ternary systems are used in some specialized computing applications (ternary logic). Some argue that base-3 is the most efficient integer base for computation, as it is the closest to the mathematical constant e ≈ 2.718.</p>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Троичная</h3>
|
||||
<p>Троичная (несимметрично-троичная) система счисления использует три цифры: 0, 1 и 2. Каждая позиция представляет степень тройки.</p>
|
||||
<h3>Как работает</h3>
|
||||
<div class="theory-example">112 = 1×9 + 1×3 + 2×1 = 14</div>
|
||||
<h3>Цифры</h3>
|
||||
<div class="theory-example">0 1 2</div>
|
||||
<h3>Применение</h3>
|
||||
<p>Троичная система используется в некоторых специализированных вычислениях (троичная логика). Некоторые считают, что троичная система является наиболее эффективной для вычислений, поскольку близка к математической константе e ≈ 2,718.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
<h3>Base: 2</h3>
|
||||
<p>The binary (base-2) numeral system uses only two digits: 0 and 1. It is the fundamental language of digital computers, where each digit represents a single bit — an electrical signal that is either off (0) or on (1).</p>
|
||||
<h3>How it works</h3>
|
||||
<p>Each position represents a power of 2, increasing from right to left:</p>
|
||||
<div class="theory-example">1011 = 1×8 + 0×4 + 1×2 + 1×1 = 11</div>
|
||||
<h3>Digits</h3>
|
||||
<div class="theory-example">0 1</div>
|
||||
<h3>Uses</h3>
|
||||
<p>Binary is used internally by all modern computers. File storage, memory addresses, and network protocols all rely on binary representation at the lowest level.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
<h3>Двоичная система</h3>
|
||||
<p>Двоичная система счисления использует только две цифры: 0 и 1. Это основной язык цифровых компьютеров, где каждый бит представляет электрический сигнал — выключен (0) или включен (1).</p>
|
||||
<h3>Как работает</h3>
|
||||
<p>Каждая позиция представляет степень двойки, увеличиваясь справа налево:</p>
|
||||
<div class="theory-example">1011 = 1×8 + 0×4 + 1×2 + 1×1 = 11</div>
|
||||
<h3>Цифры</h3>
|
||||
<div class="theory-example">0 1</div>
|
||||
<h3>Применение</h3>
|
||||
<p>Двоичная система используется внутри всеми современными компьютерами. Хранение файлов, адреса памяти и сетевые протоколы работают на двоичном представлении на нижнем уровне.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
<h3>Braille Decimal</h3>
|
||||
<p>Braille is a tactile writing system used by people who are visually impaired. Each digit is represented by a specific pattern of raised dots within a 2×3 cell. In this app, the Braille decimal system encodes digits 0–9.</p>
|
||||
<h3>Pattern</h3>
|
||||
<p>Each digit is preceded by the number indicator (⠼), which signals that the following characters represent numbers rather than letters.</p>
|
||||
<h3>Digits (0–9)</h3>
|
||||
<div class="theory-example">⠼⠚ ⠼⠁ ⠼⠃ ⠼⠉ ⠼⠙ ⠼⠑ ⠼⠋ ⠼⠛ ⠼⠓ ⠼⠊</div>
|
||||
<p>These correspond to: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9</p>
|
||||
<h3>Uses</h3>
|
||||
<p>Braille numerals are used in Braille books, signage, and electronic Braille displays. The number sign distinguishes numeric content from alphabetic text.</p>
|
||||
@@ -0,0 +1,9 @@
|
||||
<h3>Десятичная система, шрифт Брайля</h3>
|
||||
<p>Шрифт Брайля — это тактильная система письма, используемая людьми с нарушениями зрения. Каждая цифра представлена специальным паттерном выпуклых точек в ячейке 2×3. Цифры обозначаются теми же знаками, что и первые десять букв алфавита (A-K), но ей предшествует индикатор номера.</p>
|
||||
<h3>Структура</h3>
|
||||
<p>Каждая цифра предварена индикатором номера (⠼), который сигнализирует, что следующие символы являются числами.</p>
|
||||
<h3>Цифры (0–9)</h3>
|
||||
<div class="theory-example">⠼⠚ ⠼⠁ ⠼⠃ ⠼⠉ ⠼⠙ ⠼⠑ ⠼⠋ ⠼⠛ ⠼⠓ ⠼⠊</div>
|
||||
<p>Соответствуют: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9</p>
|
||||
<h3>Применение</h3>
|
||||
<p>Шрифтовые числа используются в книгах и информационных табличках для незрячих, на досках и электронных брайлевских дисплеях.</p>
|
||||
@@ -0,0 +1,15 @@
|
||||
<h3>Greek Numerals</h3>
|
||||
<p>Greek numerals are a decimal system that uses letters of the Greek alphabet to represent numbers. Known as Ionian or alphabetic numerals, this system was adopted around the 4th century BC.</p>
|
||||
<h3>How it works</h3>
|
||||
<p>Letters are assigned values from 1 to 9 (units), 10 to 90 (tens), and 100 to 900 (hundreds). A special mark (´, keraia) is placed after the number. Thousands are indicated by a subscript mark (͵) before the units letter.</p>
|
||||
<h3>Units (1–9)</h3>
|
||||
<div class="theory-example">α β γ δ ε ϛ ζ η θ</div>
|
||||
<p>(α=1, β=2, γ=3, δ=4, ε=5, ϛ=6, ζ=7, η=8, θ=9)</p>
|
||||
<h3>Tens (10–90)</h3>
|
||||
<div class="theory-example">ι κ λ μ ν ξ ο π ϟ</div>
|
||||
<p>(ι=10, κ=20, λ=30, μ=40, ν=50, ξ=60, ο=70, π=80, ϟ=90)</p>
|
||||
<h3>Hundreds (100–900)</h3>
|
||||
<div class="theory-example">ρ σ τ υ φ χ ψ ω ϡ</div>
|
||||
<p>(ρ=100, σ=200, τ=300, υ=400, φ=500, χ=600, ψ=700, ω=800, ϡ=900)</p>
|
||||
<h3>Example</h3>
|
||||
<div class="theory-example">ηπε = 8 + 80 + 5 = 93’</div>
|
||||
@@ -0,0 +1,18 @@
|
||||
<h3>Греческие числа</h3>
|
||||
<p>Греческие числа — алфавитная система записи десятичных чисел, использующая буквы греческого алфавита. Известна как ионическая или новогреческая, была популярна с IV-III века до н.э. и стала образцом для других алфавитных систем, в частности церковнославянской и еврейской</p>
|
||||
<h3>Как работает</h3>
|
||||
<p>Буквам присваиваются значения от 1 до 9 (единицы), 10 до 90 (десятки) и 100 до 900 (сотни). Число завершается символом кераия (´). Тысячи обозначаются индиксом (͵) перед буквой единиц.</p>
|
||||
<h3>Единицы (1–9)</h3>
|
||||
<div class="theory-example">α β γ δ ε ϛ ζ η θ</div>
|
||||
<p>(α=1, β=2, γ=3, δ=4, ε=5, ϛ=6, ζ=7, η=8, θ=9)</p>
|
||||
<h3>Десятки (10–90)</h3>
|
||||
<div class="theory-example">ι κ λ μ ν ξ ο π ϟ</div>
|
||||
<p>(ι=10, κ=20, λ=30, μ=40, ν=50, ξ=60, ο=70, π=80, ϟ=90)</p>
|
||||
<h3>Сотни (100–900)</h3>
|
||||
<div class="theory-example">ρ σ τ υ φ χ ψ ω ϡ</div>
|
||||
<p>(ρ=100, σ=200, τ=300, υ=400, φ=500, χ=600, ψ=700, ω=800, ϡ=900)</p>
|
||||
<h3>Пример</h3>
|
||||
<div class="theory-example">ηπε = 8 + 80 + 5 = 93’</div>
|
||||
<h3>Применение</h3>
|
||||
<p>До сих пор иногда используется для записи ординальных чисел в Греции.</p>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<h3>Hebrew Numerals</h3>
|
||||
<p>Hebrew numerals are an alphanumeric system where letters of the Hebrew alphabet are assigned numerical values. Known as "gematria," this system has been used for centuries in Jewish tradition.</p>
|
||||
<h3>How it works</h3>
|
||||
<p>Letters represent values from 1–9 (units), 10–90 (tens), and 100–400 (hundreds). Numbers are written by combining letters, with the larger values first. A single apostrophe (geresh, ׳) follows single-letter numbers, and a double apostrophe (gershayim, ״) is placed before the last letter of multi-letter numbers.</p>
|
||||
<h3>Special cases</h3>
|
||||
<p>15 and 16 use טו and טז instead of יה and יו to avoid writing God's name.</p>
|
||||
<h3>Units (1–9)</h3>
|
||||
<div class="theory-example">א ב ג ד ה ו ז ח ט</div>
|
||||
<p>(א=1, ב=2, ג=3, ד=4, ה=5, ו=6, ז=7, ח=8, ט=9)</p>
|
||||
<h3>Tens (10–90)</h3>
|
||||
<div class="theory-example">י כ ל מ נ ס ע פ צ</div>
|
||||
<p>(י=10, כ=20, ל=30, מ=40, נ=50, ס=60, ע=70, פ=80, צ=90)</p>
|
||||
<h3>Hundreds (100–400)</h3>
|
||||
<div class="theory-example">ק ר ש ת</div>
|
||||
<p>(ק=100, ר=200, ש=300, ת=400)</p>
|
||||
<h3>Beyond 400</h3>
|
||||
<p>Numbers above 400 are written additively by combining tav (400) with hundreds:</p>
|
||||
<div class="theory-example">500 = ת״ק = 400 + 100<br>900 = תת״ק = 400 + 400 + 100</div>
|
||||
<p>Thousands are written as the units letter followed by geresh:</p>
|
||||
<div class="theory-example">1000 = א׳<br>5000 = ה׳</div>
|
||||
<h3>Example</h3>
|
||||
<div class="theory-example">5786 = ה׳תשפ״ו = 5000 + 400 + 300 + 80 + 6</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<h3>Еврейские числа</h3>
|
||||
<p>Еврейские числа — алфавитная система, в которой буквам алфавита присваиваются числовые значения. Известна как гематрия, эта система является адаптацией греческой записи чисел и получила распространение около II в до н.э., заменив более древние системы на базе Арамейского и Финикийского алфаитов.</p>
|
||||
<h3>Как работает</h3>
|
||||
<p>Буквы представляют значения 1–9 (единицы), 10–90 (десятки) и 100–400 (сотни). Числа пишутся комбинацией букв, по правилу от больших к меньшим. Однобуквенные числа завершаются герешем (׳), многобуквенные — гершайми (״) перед последней буквой.</p>
|
||||
<h3>Специальные случаи</h3>
|
||||
<p>15 и 16 пишутся как טו и טז вместо יה и יו, чтобы не писать имя Б-га.</p>
|
||||
<h3>Единицы (1–9)</h3>
|
||||
<div class="theory-example">א ב ג ד ה ו ז ח ט</div>
|
||||
<p>(א=1, ב=2, ג=3, ד=4, ה=5, ו=6, ז=7, ח=8, ט=9)</p>
|
||||
<h3>Десятки (10–90)</h3>
|
||||
<div class="theory-example">י כ ל מ נ ס ע פ צ</div>
|
||||
<p>(י=10, כ=20, ל=30, מ=40, נ=50, ס=60, ע=70, פ=80, צ=90)</p>
|
||||
<h3>Сотни (100–400)</h3>
|
||||
<div class="theory-example">ק ר ש ת</div>
|
||||
<p>(ק=100, ר=200, ש=300, ת=400)</p>
|
||||
<h3>Свыше 400</h3>
|
||||
<p>Числа более 400 записываются аддитивно сочетанием ת (400) с сотными:</p>
|
||||
<div class="theory-example">500 = ת״ק = 400 + 100<br>900 = תת״ק = 400 + 400 + 100</div>
|
||||
<p>Тысячи обозначаются буквой единиц с герешом:</p>
|
||||
<div class="theory-example">1000 = א׳<br>5000 = ה׳</div>
|
||||
<h3>Пример</h3>
|
||||
<div class="theory-example">5786 = ה׳תשפ״ו = 5000 + 400 + 300 + 80 + 6</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Base: 16</h3>
|
||||
<p>The hexadecimal (base-16) numeral system uses sixteen symbols: the digits 0–9 and the letters A–F (representing values 10–15).</p>
|
||||
<h3>How it works</h3>
|
||||
<div class="theory-example">1A3 = 1×256 + 10×16 + 3×1 = 419</div>
|
||||
<h3>Digits</h3>
|
||||
<div class="theory-example">0 1 2 3 4 5 6 7 8 9 A B C D E F</div>
|
||||
<h3>Uses</h3>
|
||||
<p>Hexadecimal is ubiquitous in computing. Memory addresses, color codes in CSS (#E94560), MAC addresses, and file hashes all use hex because each hex digit maps to exactly four binary digits, making it a compact and human-readable representation of binary data.</p>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Шестнадцатеричная система</h3>
|
||||
<p>Шестнадцатеричная система счисления использует шестнадцать символов: цифры 0–9 и буквы A–F (значения 10–15).</p>
|
||||
<h3>Как работает</h3>
|
||||
<div class="theory-example">1A3 = 1×256 + 10×16 + 3×1 = 419</div>
|
||||
<h3>Цифры</h3>
|
||||
<div class="theory-example">0 1 2 3 4 5 6 7 8 9 A B C D E F</div>
|
||||
<h3>Применение</h3>
|
||||
<p>Шестнадцатеричная система повсеместно используется в компьютерной технике для компактной записи значений байт, поскольку каждая шестнадцатерная цифра соответствует четырем двоичным или полубайту.</p>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Base: 8</h3>
|
||||
<p>The octal (base-8) numeral system uses eight digits: 0 through 7. Each position represents a power of 8.</p>
|
||||
<h3>How it works</h3>
|
||||
<div class="theory-example">177 = 1×64 + 7×8 + 7×1 = 127</div>
|
||||
<h3>Digits</h3>
|
||||
<div class="theory-example">0 1 2 3 4 5 6 7</div>
|
||||
<h3>Uses</h3>
|
||||
<p>Octal was widely used in early computing (e.g. PDP-8, IBM mainframes) because it provides a compact way to represent binary numbers: each octal digit maps to exactly three binary digits. Today it appears in Unix file permissions (chmod 755) and some legacy systems.</p>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3>Восьмеричная система</h3>
|
||||
<p>Восьмеричная система счисления использует восемь цифр: 0–7. Каждая позиция представляет степень восьми.</p>
|
||||
<h3>Как работает</h3>
|
||||
<div class="theory-example">177 = 1×64 + 7×8 + 7×1 = 127</div>
|
||||
<h3>Цифры</h3>
|
||||
<div class="theory-example">0 1 2 3 4 5 6 7</div>
|
||||
<h3>Применение</h3>
|
||||
<p>Восьмеричная система была распространена в раннем программировании (например PDP-8, главные ЭВМ IBM), т.к. каждая восьмеричная цифра соответствует трем двоичным. Сейчас встречается в правах доступа к файлам Unix (chmod 755) и некоторых устаревших системах.</p>
|
||||
@@ -0,0 +1,11 @@
|
||||
<h3>Roman Numerals</h3>
|
||||
<p>Roman numerals originated in ancient Rome and remained the standard way of writing numbers throughout Europe well into the Middle Ages. They use combinations of letters from the Latin alphabet.</p>
|
||||
<h3>Symbols</h3>
|
||||
<div class="theory-example">I = 1 V = 5 X = 10 L = 50 C = 100 D = 500 M = 1000</div>
|
||||
<h3>How it works</h3>
|
||||
<p>Roman numerals are primarily additive: values are summed left to right. However, a smaller value placed before a larger one indicates subtraction:</p>
|
||||
<div class="theory-example">IV = 5 − 1 = 4 IX = 10 − 1 = 9<br>XL = 50 − 10 = 40 XC = 100 − 10 = 90 CM = 1000 − 100 = 900</div>
|
||||
<h3>Examples</h3>
|
||||
<div class="theory-example">XLII = 40 + 2 = 42<br><br>MCMXCIV = 1000 + 900 + 90 + 4 = 1994</div>
|
||||
<h3>Rules</h3>
|
||||
<p>Roman numerals can represent numbers from 1 to 3999. I, X, C, and M can be repeated up to three times. V, L, and D are never repeated. The subtractive combinations IV, IX, XL, XC, CM, and CD are the only allowed subtractions.</p>
|
||||
@@ -0,0 +1,11 @@
|
||||
<h3>Римские числа</h3>
|
||||
<p>Римские числа возникли в древнем Риме и оставались стандартным способом записи чисел в Европе до Средневековья. Они используют буквы латинского алфавита.</p>
|
||||
<h3>Символы</h3>
|
||||
<div class="theory-example">I = 1 V = 5 X = 10 L = 50 C = 100 D = 500 M = 1000</div>
|
||||
<h3>Как работает</h3>
|
||||
<p>Римские числа преимущественно аддитивны: значения складываются слева направо. Однако меньшая цифра перед большей означает вычитание:</p>
|
||||
<div class="theory-example">IV = 5 − 1 = 4 IX = 10 − 1 = 9<br>XL = 50 − 10 = 40 XC = 100 − 10 = 90 CM = 1000 − 100 = 900</div>
|
||||
<h3>Примеры</h3>
|
||||
<div class="theory-example">XLII = 40 + 2 = 42<br><br>MCMXCIV = 1000 + 900 + 90 + 4 = 1994</div>
|
||||
<h3>Правила</h3>
|
||||
<p>Римские числа могут представлять числа от 1 до 3999. I, X, C и M могут повторяться до трех раз. V, L и D никогда не повторяются.</p>
|
||||
@@ -0,0 +1,15 @@
|
||||
<h3>Church Slavonic Numerals</h3>
|
||||
<p>Church Slavonic numerals are a Cyrillic alphanumeric system used historically in Russian and other Slavic Orthodox cultures. Letters of the early Cyrillic alphabet are assigned numerical values.</p>
|
||||
<h3>How it works</h3>
|
||||
<p>Like Greek numerals, Church Slavonic uses separate letter groups for units (1–9), tens (10–90), and hundreds (100–900). A titlo mark (<span class="slavonic-font"> ҃</span>) is placed above one of the letters to indicate it is a number. Thousands are marked with a special symbol (<span class="slavonic-font">҂</span>) placed before the number. The number ends with a period.</p>
|
||||
<h3>Units (1–9)</h3>
|
||||
<div class="theory-example slavonic-font">а в г д є ѕ з и ѳ</div>
|
||||
<p>(<span class="slavonic-font">а</span>=1, <span class="slavonic-font">в</span>=2, <span class="slavonic-font">г</span>=3, <span class="slavonic-font">д</span>=4, <span class="slavonic-font">є</span>=5, <span class="slavonic-font">ѕ</span>=6, <span class="slavonic-font">з</span>=7, <span class="slavonic-font">и</span>=8, <span class="slavonic-font">ѳ</span>=9)</p>
|
||||
<h3>Tens (10–90)</h3>
|
||||
<div class="theory-example slavonic-font">і к л м н ѯ ѻ п ч</div>
|
||||
<p>(<span class="slavonic-font">і</span>=10, <span class="slavonic-font">к</span>=20, <span class="slavonic-font">л</span>=30, <span class="slavonic-font">м</span>=40, <span class="slavonic-font">н</span>=50, <span class="slavonic-font">ѯ</span>=60, <span class="slavonic-font">ѻ</span>=70, <span class="slavonic-font">п</span>=80, <span class="slavonic-font">ч</span>=90)</p>
|
||||
<h3>Hundreds (100–900)</h3>
|
||||
<div class="theory-example slavonic-font">р с т у ф х ѱ Ѿ ц</div>
|
||||
<p>(<span class="slavonic-font">р</span>=100, <span class="slavonic-font">с</span>=200, <span class="slavonic-font">т</span>=300, <span class="slavonic-font">у</span>=400, <span class="slavonic-font">ф</span>=500, <span class="slavonic-font">х</span>=600, <span class="slavonic-font">ѱ</span>=700, <span class="slavonic-font">Ѿ</span>=800, <span class="slavonic-font">ц</span>=900)</p>
|
||||
<h3>Example</h3>
|
||||
<div class="theory-example slavonic-font">цп҃з. = 900 + 80 + 3 = 983</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<h3>Церковнославянские числа</h3>
|
||||
<p>Церковнославянские числа — кириллическая цифровая система, использующаяся в русской и других славянских православных культурах. Буквы древней кириллической азбуки, имеющие греческие аналоги, имеют числовые значения, равные значениям в греческой системе записи.</p>
|
||||
<h3>Как работает</h3>
|
||||
<p>Используются отдельные группы букв для единиц (1–9), десятков (10–90) и сотен (100–900). Над буквой ставится титло (<span class="slavonic-font"> ҃</span>). Тысячи обозначаются специальным знаком (<span class="slavonic-font">҂</span>). Число завершается точкой.</p>
|
||||
<h3>Единицы (1–9)</h3>
|
||||
<div class="theory-example slavonic-font">а в г д є ѕ з и ѳ</div>
|
||||
<p>(<span class="slavonic-font">а</span>=1, <span class="slavonic-font">в</span>=2, <span class="slavonic-font">г</span>=3, <span class="slavonic-font">д</span>=4, <span class="slavonic-font">є</span>=5, <span class="slavonic-font">ѕ</span>=6, <span class="slavonic-font">з</span>=7, <span class="slavonic-font">и</span>=8, <span class="slavonic-font">ѳ</span>=9)</p>
|
||||
<h3>Десятки (10–90)</h3>
|
||||
<div class="theory-example slavonic-font">і к л м н ѯ ѻ п ч</div>
|
||||
<p>(<span class="slavonic-font">і</span>=10, <span class="slavonic-font">к</span>=20, <span class="slavonic-font">л</span>=30, <span class="slavonic-font">м</span>=40, <span class="slavonic-font">н</span>=50, <span class="slavonic-font">ѯ</span>=60, <span class="slavonic-font">ѻ</span>=70, <span class="slavonic-font">п</span>=80, <span class="slavonic-font">ч</span>=90)</p>
|
||||
<h3>Сотни (100–900)</h3>
|
||||
<div class="theory-example slavonic-font">р с т у ф х ѱ Ѿ ц</div>
|
||||
<p>(<span class="slavonic-font">р</span>=100, <span class="slavonic-font">с</span>=200, <span class="slavonic-font">т</span>=300, <span class="slavonic-font">у</span>=400, <span class="slavonic-font">ф</span>=500, <span class="slavonic-font">х</span>=600, <span class="slavonic-font">ѱ</span>=700, <span class="slavonic-font">Ѿ</span>=800, <span class="slavonic-font">ц</span>=900)</p>
|
||||
<h3>Пример</h3>
|
||||
<div class="theory-example slavonic-font">цп҃з. = 900 + 80 + 3 = 983</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<h3>Balanced Ternary: Base 3 with signed digits</h3>
|
||||
<p>Balanced ternary is a positional Base 3 system where non-zero digits are signed: −1, 0, or +1. Instead of using the digits -1 and +1, any suitable symbols can be used, we use circled - and +:</p>
|
||||
<h3>Digits</h3>
|
||||
<div class="theory-example">⊖ = −1, 0 = 0, ⊕ = +1</div>
|
||||
<p>⊖ (Circled Minus) represents −1, and ⊕ (Circled Plus) represents +1.</p>
|
||||
<h3>How it works</h3>
|
||||
<p>Each position represents a power of 3, but positions can be negative:</p>
|
||||
<div class="theory-example">⊕0⊖ = (+1)×9 + 0×3 + (−1)×1 = 8</div>
|
||||
<div class="theory-example">⊖⊕0 = (-1)×9 + (+1)×3 + 0×1 = -6</div>
|
||||
<h3>Properties</h3>
|
||||
<p>Balanced ternary has the unique property that the sign of a number can be determined from its most significant non-zero digit, eliminating the need for a separate sign. For negative numbers, the signs of all non-zero digits are flipped (⊕ ↔ ⊖). The system was studied by Leonardo Pisano (Fibonacci, 1170–1250) in connection with the weight problem — using weights of powers of 3, any integer mass from 1 can be measured with the fewest weights. In 1958, the Soviet engineer Nikolai Brusentsov built the Setun computer at Moscow State University, which used balanced ternary arithmetic and became one of the most elegant ternary computers.</p>
|
||||
@@ -0,0 +1,11 @@
|
||||
<h3>Симметричная троичная система</h3>
|
||||
<p>Симметричная (уравновешенная) троичная система — это позиционная система по основанию три, использующая цифры со значениями −1, 0 или +1. Значения -1 и +1 для удобства могут обозначаться по-разному, любыми подходящими симполами, стандарта не существует. Мы используем знаки "-" и "+" в окружностях:</p>
|
||||
<h3>Цифры</h3>
|
||||
<div class="theory-example">⊖ = −1, 0 = 0, ⊕ = +1</div>
|
||||
<p>⊖ (Кружок с минусом) обозначает −1, а ⊕ (Кружок с плюсом) — +1.</p>
|
||||
<h3>Как работает</h3>
|
||||
<p>Каждая позиция представляет степень тройки, значение в позиции становится отрицательным, если в нем стоит -1:</p>
|
||||
<div class="theory-example">⊕0⊖ = (+1)×9 + 0×3 + (−1)×1 = 8</div>
|
||||
<div class="theory-example">⊖⊕0 = (-1)×9 + (+1)×3 + 0×1 = -6</div>
|
||||
<h3>Свойства</h3>
|
||||
<p>Самая экономичная среди целочисленных позиционных систем. В симметричной троичной системе знак числа определяется по первой ненулевой цифре старшего разряда, что устраняет необходимость использовать отдельный знак для отрицательных чисел. Для смены знака числа ненулевые цифры инвертируются (⊕ ↔ ⊖). Эту систему изучал Леонардо Писано (Фибоначчи, 1170–1250) в связи с задачей о гирях: используя гири массой со степенями тройки, любую целую массу можно отвесить минимальным числом гирь. В 1958 году советский инженер Николай Брусенцов спроектировал ЭВМ Сетунь, который использовал симметрично-троичную арифметику и стал одним из самых элегантных троичных компьютеров.</p>
|
||||
Reference in New Issue
Block a user