Викиучебник
ruwikibooks
https://ru.wikibooks.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0
MediaWiki 1.47.0-wmf.6
first-letter
Медиа
Служебная
Обсуждение
Участник
Обсуждение участника
Викиучебник
Обсуждение Викиучебника
Файл
Обсуждение файла
MediaWiki
Обсуждение MediaWiki
Шаблон
Обсуждение шаблона
Справка
Обсуждение справки
Категория
Обсуждение категории
Полка
Обсуждение полки
Импортировано
Обсуждение импортированного
Рецепт
Обсуждение рецепта
Задача
Обсуждение задачи
TimedText
TimedText talk
Модуль
Обсуждение модуля
Event
Event talk
Реализации алгоритмов/Алгоритм Евклида
0
6312
269073
255627
2026-06-10T07:30:14Z
Yevrowl
11674
/* Galaksija BASIC */
269073
wikitext
text/x-wiki
Реализации [[w:алгоритм Евклида|алгоритма Евклида]] для вычисления НОД — наибольшего общего делителя (англ. GCD — greatest common divisor) двух целых чисел на различных [[w:язык программирования|языках программирования]].
=Описание=
'''Классический алгоритм Евклида''' применяется к паре неотрицательных целых чисел. Пока ни одно из чисел в паре не равно нулю, из большего числа вычитается меньшее; вычитаемое и полученная разность формируют новую пару. Действие повторяется, пока один из элементов пары не обратится в 0, тогда значение другого будет равно искомому НОД.
Рекурсивная формулировка классического алгоритма:
* НОД(a, 0) = a
* НОД(a, b) = НОД(a, a − b) при a ≥ b
* НОД(a, b) = НОД(b, b − a) при a < b
Несложно заметить, что последовательное вычитание из большего числа меньшего, пока разность не станет меньше вычитаемого, соответствует нахождению остатка от деления большего числа на меньшее. На этом основан так называемый '''быстрый алгоритм Евклида''': в паре чисел одно число делится с остатком на второе; делитель и полученный остаток формируют новую пару. Действие повторяется, пока один из элементов пары не обратится в 0, тогда значение другого будет равно искомому НОД.
Рекурсивная формулировка быстрого алгоритма:
* НОД(a, 0) = a
* НОД(a, b) = НОД(b, ОСТАТОК(a / b))
Оба алгоритма обобщаются на ноль и отрицательные значения. При этом следует иметь ввиду:
* Помимо положительных общих делителей у чисел имеются и отрицательные. Однако наибольший общий делитель по определению не может быть отрицательным (очевидно, что любое положительное число больше любого отрицательного). Таким образом НОД двух чисел равен НОДу их модулей.
* Если одно из чисел в паре равно нулю, а другое — нет, то их НОД равен модулю ненулевого числа.
* НОД пары нулей может рассматриваться, как неопределённое значение или бесконечность, а может [https://math.stackexchange.com/questions/495119/what-is-gcd0-0 приниматься равным нулю]. Приведённые реализации в основном придерживаются последнего подхода (технически он реализуется проще).
* Подавляющее большинство языков программирования представляют отрицательные целые числа в так называемом [[w:Дополнительный_код|дополнительном коде]], при этом у наименьшего отрицательного значения типа отсутствует парное положительное значение (например наименьшее значение 16-битного знакового целого — −32768, а наибольшее — 32767). Следовательно вычисление НОД с применением наименьшего значения знакового типа может вызывать переполнение и давать неверные результаты.
Как правило, языки программирования включают функцию или оператор нахождения остатка от деления двух чисел, поэтому соответствующие реализации используют именно быстрый алгоритм Евклида. Алгоритм, построенный на вычитании, имеет смысл использовать на тех системах, где встроенная операция нахождения остатка отсутствует и её невыгодно эмулировать, например, через деление и взятие целой части.
=Реализации=
==[[w:Язык_ассемблера|Assembler]]==
===ARM===
Вычитание, цикл:
<syntaxhighlight lang="arm">
loop CMP Ri, Rj ; проверка условий NE (i != j), GT (i > j) и LT (i < j);
SUBGT Ri, Ri, Rj ; если GT, выполняется i = i-j;
SUBLT Rj, Rj, Ri ; если LT, выполняется j = j-i;
BNE loop ; если NE - переход на метку loop.
</syntaxhighlight>
===Z80===
Вычитание, цикл:
<syntaxhighlight lang="z80">
GCD_DEHL: ; CALL Inputs: HL,DE; Output: DE
AND A ; сброс CF
LOOP:
SBC HL,DE ; совмещение трёх в одном - одного сравнения и поочередно двух вычитаний.
RET Z ; минимизация общего размера, поэтому в цикле.
JR NC,LOOP
ADD HL,DE ; откат лишнего вычитания
EX DE,HL
JR GCD_DEHL
</syntaxhighlight>
==[[w:Бейсик|BASIC]]==
===Классический===
Цикл, вычитание (операция нахождения остатка MOD отсутствовала в этой версии языка):
<syntaxhighlight lang="basic">
10 PRINT "Two integer numbers";
20 INPUT A, B
30 PRINT "GCD("; A; ", "; B,") = ";
40 LET A = ABS(A)
50 IF B = 0 THEN GOTO 120
60 LET B = ABS(B)
70 IF A < B THEN GOTO 90
80 LET A = A - B: GOTO 70
90 IF A = 0 THEN LET A = B: GOTO 120
100 LET B = B - A: IF B >= A THEN GOTO 100
110 IF B > 0 THEN GOTO 80
120 PRINT A
130 END
</syntaxhighlight>
===[[w:Galaksija BASIC|Galaksija BASIC]]===
<syntaxhighlight lang="basic">
10 PRINT "Two integer numbers"
20 PRINT "A = ";: INPUT A
30 PRINT "B = ";: INPUT B
40 PRINT "GCD("; A; ", "; B; ") = ";
50 A = ABS(A)
60 IF B = 0 GOTO 150
70 B = ABS(B)
80 IF A < B GOTO 100
90 A = A - B: GOTO 80
100 IF A = 0 A = B: GOTO 150
110 B = B - A
120 IF B = A GOTO 110
130 IF B > A GOTO 110
140 IF B > 0 GOTO 90
150 PRINT A
160 STOP
</syntaxhighlight>
===[[w:GW-BASIC|GW-BASIC]] и совместимые диалекты===
Цикл, деление с остатком:
<syntaxhighlight lang="basic">
10 INPUT "Two integer numbers", A%, B%
20 PRINT "GCD("; A%; ", "; B%; ") = ";
30 WHILE B% <> 0
40 A% = A% MOD B%
50 IF A% = 0 THEN A% = B%: B% = 0: ELSE B% = B% MOD A%
60 WEND
70 PRINT ABS(A%)
</syntaxhighlight>
===[[w:QuickBasic|QuickBasic]] версий < 4.0, [[w:Turbo Basic|Turbo Basic]]===
Цикл, деление с остатком:
<syntaxhighlight lang="basic">
DEF FNGCD%(A%, B%)
DO UNTIL B% = 0
A% = A% MOD B%
IF A% = 0 THEN
FNGCD% = ABS(B%)
EXIT DEF
END IF
B% = B% MOD A%
LOOP
FNGCD% = ABS(A%)
END DEF
</syntaxhighlight>
===[[w:PowerBASIC|PowerBASIC]], [[w:QBASIC|QBASIC]], [[w:QuickBasic|QuickBasic]] версий 4.X, [[w:Visual Basic|Visual Basic]] версий ≤ 6.0, [[w:Visual Basic for Applications|Visual Basic для приложений]]===
В следующих примерах используется тип <code>Long</code> (длинное целое); вместо него можно применять также тип <code>Integer</code> (стандартное целое).
Цикл, деление с остатком:
<syntaxhighlight lang="vb">
Function GCD(a As Long, b As Long) As Long
Do Until b = 0
a = a Mod b
If a = 0 Then
GCD = b
Exit Function
End If
b = b Mod a
Loop
GCD = a
End Function
</syntaxhighlight>
Рекурсия, деление с остатком:
<syntaxhighlight lang="vb">
Function GCD(a As Long, b As Long) As Long
If b = 0 Then
GCD = Abs(a)
Else
GCD = GCD(b, a Mod b)
End If
End Function
</syntaxhighlight>
===[[w:VB.NET|Visual Basic .NET]]===
В следующих примерах используется тип <code>Long</code> (длинное целое); вместо него можно применять любые другие целочисленные типы платформы [[w:NET_Framework|.NET]].
Цикл, деление с остатком:
<syntaxhighlight lang="vb">
Function GCD(ByVal a As Long, ByVal b As Long) As Long
Do Until b = 0
a = a Mod b
If a = 0 Then Return Math.Abs(b)
b = b Mod a
Loop
Return Math.Abs(a)
End Function
</syntaxhighlight>
Рекурсия, деление с остатком:
<syntaxhighlight lang="vb">
Function GCD(ByVal a As Long, ByVal b As Long) As Long
Return If(b = 0, Math.Abs(a), GCD(b, a Mod b)) ' VB.NET 2008 или более поздняя версия
End Function
</syntaxhighlight>
==[[w:C (язык программирования)|C]]/[[w:C++|C++]]==
'''C:''' Тип <code>Integer</code> должен быть задан как:
<syntaxhighlight lang="c">typedef int Integer; /* Вместо int можно подставить любой другой целочисленный тип */</syntaxhighlight>
'''C++:''' Любую из нижеприведённых функций (включая <code>abs</code>) следует предварить строкой:
<syntaxhighlight lang="cpp">template <typename Integer></syntaxhighlight>
Для корректной обработки отрицательных чисел все последующие примеры на C/C++ используют функцию вычисления модуля числа:
<syntaxhighlight lang="c">
Integer abs (Integer value) {
return (value < 0) ? -value : value;
}
</syntaxhighlight>
Деление с остатком, цикл:
<syntaxhighlight lang="c">
Integer gcd (Integer a, Integer b) {
for (Integer c; b; ) {
c = a % b;
a = b;
b = c;
}
return abs(a);
}
</syntaxhighlight>
Без использования дополнительной переменной:
<syntaxhighlight lang="c">
Integer gcd (Integer a, Integer b) {
while (b)
b ^= a ^= b ^= a %= b;
return abs(a);
}
</syntaxhighlight>
Без использования дополнительной переменной и с наименьшим числом сравнений и присваиваний:
<syntaxhighlight lang="c">
Integer gcd (Integer a, Integer b) {
if (!a)
return abs(b);
if (!b)
return abs(a);
for ( ; ; )
if (!(a %= b))
return abs(b);
else if (!(b %= a))
return abs(a);
}
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="c">
Integer gcd (Integer a, Integer b) {
return !b ? abs(a) : gcd(b, a % b);
}
</syntaxhighlight>
Вычитание, цикл:
<syntaxhighlight lang="c">
Integer gcd (Integer a, Integer b) {
a = abs(a);
b = abs(b);
while (b) {
while (a >= b)
a -= b;
if (!a)
return b;
do {
b -= a;
} while (b >= a);
}
return a;
}
</syntaxhighlight>
==[[w:C_Sharp|C#]], [[w:Java|Java]]==
Приведён код для C#. Для Java следует заменить <code>Abs</code> на <code>abs</code> и, для соответствия правилам оформления кода, переименовать функции в <code>gcd</code> и перенести <code>{</code> в конец предыдущей строки.
Вместо <code>long</code> можно использовать и другие целочисленные типы — <code>byte</code>, <code>int</code> и т. д.
Деление с остатком, цикл:
<syntaxhighlight lang="csharp">
static long GCD(long a, long b)
{
while (b != 0)
b = a % (a = b);
return Math.Abs(a);
}
</syntaxhighlight>
<syntaxhighlight lang="csharp">
static long GCD(long a, long b)
{
if (a == 0)
return Math.Abs(b);
if (b == 0)
return Math.Abs(a);
for ( ; ; )
if ((a %= b) == 0)
return Math.Abs(b);
else if ((b %= a) == 0)
return Math.Abs(a);
}
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="csharp">
static long GCD (long a, long b)
{
return b == 0 ? Math.Abs(a) : GCD(b, a % b);
}
</syntaxhighlight>
==[[w:Erlang|Erlang]]==
Деление с остатком, рекурсия:
<syntaxhighlight lang="erlang">
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, (A rem B)).
</syntaxhighlight>
==[[w:F_Sharp|F#]]==
Деление с остатком, рекурсия:
<syntaxhighlight lang="fsharp">
let rec gcd a b =
match b with
|0 -> a
|b -> gcd b (a % b)
</syntaxhighlight>
==[[w:Forth (язык программирования)|Forth]] (диалект [[RetroForth]])==
Деление с остатком, рекурсия:
<syntaxhighlight lang="forth">
: GCD ( n1 n2 -- n ) tuck mod 0; GCD ;
</syntaxhighlight>
==[[w:Go|Go]]==
Тип <code>Integer</code> определён как:
<syntaxhighlight lang="go">
type Integer = int // Вместо int можно подставить любой другой целочисленный тип
</syntaxhighlight>
Для корректной обработки отрицательных чисел все последующие примеры на Go используют функцию вычисления модуля числа:
<syntaxhighlight lang="go">
func IntAbs(value Integer) Integer {
if value < 0 {
return -value
}
return value
}
</syntaxhighlight>
Деление с остатком, цикл:
<syntaxhighlight lang="go">
func GCD(a, b Integer) Integer {
for b != 0 {
a %= b
if a == 0 {
return IntAbs(b)
}
b %= a
}
return IntAbs(a)
}
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="go">
func GCD(a, b Integer) Integer {
if b == 0 {
return IntAbs(a)
}
return GCD(b, a % b)
}
</syntaxhighlight>
==[[w:Haskell|Haskell]]==
Деление с остатком, рекурсия:
<syntaxhighlight lang="haskell">
gcd :: Integral a => a -> a -> a
gcd 0 0 = error "НОД от 0 и 0 не определён."
gcd x y = gcd' (abs x) (abs y)
where gcd' x 0 = x
gcd' x y = gcd' y (x `rem` y)
</syntaxhighlight>
==[[w:JavaScript|JavaScript]], [[w:ECMAScript|ECMAScript]]==
Деление с остатком, цикл:
<syntaxhighlight lang="js">
function gcd(a, b) {
if (a === 0)
return Math.abs(b);
if (b === 0)
return Math.abs(a);
for ( ; ; )
if ((a %= b) === 0)
return Math.abs(b);
else if ((b %= a) === 0)
return Math.abs(a);
}
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="js">
const gcd = (a, b) => b === 0 ? Math.abs(a) : gcd(b, a % b); // ECMAScript версий ≥ 6.0
</syntaxhighlight>
==[[w:Паскаль (язык программирования)|Pascal]]==
Тип <code>TInteger</code> определён как:
<syntaxhighlight lang="pascal">
type TInteger = Integer; { Вместо Integer можно подставить любой другой целочисленный тип }
</syntaxhighlight>
Деление с остатком, цикл:
<syntaxhighlight lang="pascal">
function GCD(a, b: TInteger): TInteger;
begin
while b <> 0 do
begin
a := a mod b;
if a = 0 then
begin
a := b;
b := 0
end
else
b := b mod a
end;
GCD := Abs(a)
end;
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="pascal">
function GCD(a, b: TInteger): TInteger;
begin
if b = 0 then
GCD := Abs(a)
else
GCD := GCD(b, a mod b)
end;
</syntaxhighlight>
==[[w:Perl|Perl]]==
Деление с остатком, рекурсия:
<syntaxhighlight lang="perl">
sub gcd {
return $_[0] != 0 ? gcd ( ( $_[1] % $_[0] ), $_[0] ) : $_[1];
}
</syntaxhighlight>
==[[w:PHP|PHP]]==
Деление с остатком, цикл:
<syntaxhighlight lang="php">
function gcd ($a, $b) {
if ($a === 0)
return abs($b);
if ($b === 0)
return abs($a);
for ( ; ; )
if (($a %= $b) === 0)
return abs($b);
else if (($b %= $a) === 0)
return abs($a);
}
</syntaxhighlight>
==[[w:Пролог (язык программирования)|Prolog]]==
Деление с остатком, рекурсия:
<syntaxhighlight lang="prolog">
?GCD(a, b, x)
GCD(0, b, b) <-
GCD(a, 0, a) <-
GCD(a, b, x) <- a >= b, m is a mod b, GCD(m, b, x)
GCD(a, b, x) <- a < b, m is b mod a, GCD(a, m, x)
</syntaxhighlight>
===[[w:SWI-Prolog|SWI-Prolog]]===
Деление с остатком, рекурсия:
<syntaxhighlight lang="prolog">
gcd(0, B, B).
gcd(A, 0, A).
gcd(A, B, X) :- A >= B, M is A mod B, gcd(M, B, X).
gcd(A, B, X) :- A < B, M is B mod A, gcd(A, M, X).
</syntaxhighlight>
==[[w:Python|Python]]==
Деление с остатком, цикл:
<syntaxhighlight lang="python">
def gcd(a: int, b: int) -> int:
while b:
a, b = b, a % b
return abs(a)
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="python">
def gcd(a: int, b: int) -> int:
return abs(a) if b == 0 else gcd(b, a % b)
</syntaxhighlight>
==[[:Ruby|Ruby]]==
Деление с остатком, цикл:
<syntaxhighlight lang="ruby">
def gcd(a, b)
a, b = b, a % b until b.zero?
a.abs
end
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="ruby">
def gcd(a, b)
return a.abs if b.zero?
gcd(b, a % b)
end
</syntaxhighlight>
==[[w:Rust (язык программирования)|Rust]]==
Деление с остатком, цикл:
<syntaxhighlight lang="rust">
use num::Zero;
use std::ops::{RemAssign, Sub};
fn gcd <Integer> (a: Integer, b: Integer) -> Integer
where Integer: Zero + PartialOrd + Sub<Output = Integer> + RemAssign + Copy
{
let result: Integer;
if a.is_zero() {
result = b;
} else if b.is_zero() {
result = a;
} else {
// Вместо неизменяемых параметров a и b дальше используются переменные _a и _b
let mut _a = a;
let mut _b = b;
loop {
_a %= _b;
if _a.is_zero() {
result = _b;
break;
};
_b %= _a;
if _b.is_zero() {
result = _a;
break;
};
};
};
// `result` берётся по модулю
if result < Integer::zero() {
Integer::zero() - result
} else {
result
}
}
</syntaxhighlight>
Деление с остатком, рекурсия:
<syntaxhighlight lang="rust">
use num::Zero;
use std::ops::{Rem, Sub};
pub fn gcd <Integer> (a: Integer, b: Integer) -> Integer
where Integer: Zero + PartialOrd + Sub<Output = Integer> + Rem<Output = Integer> + Copy
{
if b.is_zero() {
// Возвращаемое значение берётся по модулю
if a < Integer::zero() {
Integer::zero() - a
} else {
a
}
} else {
gcd(b, a % b)
}
}
</syntaxhighlight>
==[[w:Scheme|Scheme]]==
Вычитание, рекурсия:
('''define''' gcd ('''lambda''' (a b)
('''if''' (> a b) ('''gcd''' (- a b) b)
('''if''' (< a b) ('''gcd''' a (- b a))
a))))
==Shell==
Деление с остатком, рекурсия:
<syntaxhighlight lang="bash">
gcd () {
n = 1 a = $1 b = $2
if [[ $a -ne 0 ]]
then
gcd $(( $b % $a )) $a
let "n = $?"
else
let "n = $b"
fi
return $n
}
gcd $1 $2
echo "Greatest common divisor is $?"
</syntaxhighlight>
==[[w:Глагол (язык программирования)|Глагол]]==
Деление с остатком, цикл:
<syntaxhighlight>
ЗАДАЧА НОД (a, b: ЦЕЛ): ЦЕЛ;
УКАЗ
ПОКА b # 0 ВЫП
a := a ОСТАТОК b;
ЕСЛИ a = 0 ТО
a := b;
b := 0
ИНАЧЕ
b := b ОСТАТОК a
КОН
КОН;
ВОЗВРАТ МОДУЛЬ(a)
КОН НОД;
</syntaxhighlight>
==Программируемые микрокалькуляторы «Электроника»==
'''Использование:''' <первое число> → регистр Y, <второе число> → регистр X, В/О, С/П (НОД на индикаторе).
===Б3-21, МК-46 / 64, МС-1103===
Вычитание, цикл. Корректно обрабатываются любые целые неотрицательные числа. В вычислениях участвуют только регистры стека X и Y.
<syntaxhighlight>
00. Px≠0 01. ↔ 02. − 03. Px≥0 04. F1 05. ↔
10. − 11. /−/ 12. ↔ 13. Px=0 14. Peⁱˣ 15. ↔
20. С/П
</syntaxhighlight>
===Б3-34, МК-54 / 56 / 61 / 52 / 161 / 163 / 152 / 1152===
Вычитание, цикл. Корректно обрабатываются любые целые неотрицательные числа. В вычислениях участвуют только регистры стека X, Y и X1.
<syntaxhighlight>
00. Fx≠0 01. 13 02. − 03. Fx<0 04. 09 05. /−/ 06. FВx 07. ↔ 08. − 09. FВx
10. ↔ 11. Fx=0 12. 02 13. + 14. С/П
</syntaxhighlight>
===МК-61 / 52 / 161 / 163 / 152 / 1152===
Деление с остатком, цикл. Корректно обрабатываются любые целые числа (включая 0 и отрицательные). В вычислениях участвуют все регистры стека.
<syntaxhighlight>
00. Fx≠0 01. 13 02. ↔ 03. В↑ 04. FВx 05. ÷ 06. FВx 07. ↔ 08. K[x] 09. ×
10. − 11. Fx=0 12. 02 13. + 14. K|x| 15. С/П
</syntaxhighlight>
==См. также==
* [[../Бинарный алгоритм вычисления НОД/]]
=Ссылки=
3b2f5zk1bnpt01p80wvpqfu9fkvf506
Реализации алгоритмов/Вечный календарь
0
9251
269072
255768
2026-06-09T20:56:11Z
Yevrowl
11674
/* Galaksija BASIC */
269072
wikitext
text/x-wiki
{{wikipedia|Вечный календарь}}
=Описание=
Существует довольно простой '''алгоритм вычисления дня недели''' для любой даты [[w:Григорианский календарь|григорианского календаря]], начиная с первого дня его действия — 15 октября [[w:1582|1582]] года. (Предыдущим днём было 4 октября, числа с 5 по 14 октября включительно были пропущены для устранения 11‑дневного отставания от фактической даты, накопившегося за время использования [[w:Юлианский календарь|юлианского календаря]]).
Положим, дата задана так: ''год'' — год (от 1582), ''месяц'' — номер месяца (1…12), ''число'' — число месяца (1…31, согласно числу дней в соответствующем месяце), тогда:
a = (14 − месяц) / 12
год = год − a
месяц = месяц + 12 * a − 2
ДеньНедели = (число + (31 * месяц) / 12 + год + год / 4 − год / 100 + год / 400) ОСТАТОК 7
либо, что почти то же самое:
если месяц = 1 или месяц = 2: // январь или февраль
год = год − 1
месяц = месяц + 10
иначе:
месяц = месяц − 2
всё
ДеньНедели = (число + (31 * месяц) / 12 + год + год / 4 − год / 100 + год / 400) ОСТАТОК 7
Деление производится нацело (с отбрасыванием остатка).
Результат: 0 — воскресенье, 1 — понедельник и т. д.
=Реализации=
==[[Arduino IDE]]==
<syntaxhighlight lang="C">
//==========================================================================================
//Глобальные переменные
//==========================================================================================
byte day = 7; //число
byte month = 7; //месяц
unsigned int year = 2017; //год
//===============================================================================================
// Функция деления без остатка f_div
// Я извиняюсь, но кому в здравом уме могла прийти идея написать отдельную функцию
// целочисленного деления в C или C++?
// Всем нормальным людям известно, что простое деление двух целых с помощью '/'
// в C или в C++ - есть целочисленное деление!!!!!!! Т.е. деление без остатка, если кто не понял.
//===============================================================================================
unsigned int f_div(unsigned int x, unsigned int y){
unsigned int result;
result = (x - (x % y)) / y;
return result;
}
//==========================================================================================
//Функция вычисления дня недели
//==========================================================================================
void weekday(){
// И вы с какой целью пытаетесь запихнуть результат функции типа unsigned int, который
// может принимать значения в диапазоне 0...65535 в переменную типа byte, которая по сути
// является unsigned char, т.е. 0...255. На выхлопе можно такое получить, что юлианский
// с григорианским календарем на пару кашлять будут разными битами во все стороны ))))
byte a = f_div((14 - month), 12);
// Ну и, конечно, надо понимать, что результат здесь для a всегда будет ноль (0), кроме
// января(1) и февраля(1)
unsigned int y = year - a;
byte m = month + 12 * a - 2;
unsigned int y4 = f_div(y, 4);
byte y100 = f_div(y, 100);
byte y400 = f_div(y, 400);
byte x = f_div(31 * m, 12);
byte wd = (day + y + y4 - y100 + y400 + x) % 7; //результат в переменной "wd"
}
//набирал с клавиатуры и убил вечер на тестирование - reodos
</syntaxhighlight>
==[[w:Бейсик|BASIC]]==
===Классический===
<syntaxhighlight lang="basic">
10 PRINT "Year";: INPUT Y
20 PRINT "Month";: INPUT M
30 PRINT "Day";: INPUT D
40 IF M < 3 THEN LET Y = Y - 1: LET M = M + 12
50 LET M = M - 2
60 LET W = (D + INT(31 * M / 12) + Y + INT(Y / 4) - INT(Y / 100) + INT(Y / 400))
70 LET W = W - INT(W / 7) * 7
80 PRINT "Weekday: "; W
90 END
</syntaxhighlight>
'''Примечание:''' При выполнении условия <code>M < 3</code> в строке 40 значение M увеличивается на 12, а в строке 50 уменьшается на 2, т. е. в итоге увеличивается на 10. При невыполнении же условия значение M просто уменьшается на 2. Таким образом удаётся избежать использования оператора <code>GOTO</code>.
===[[w:Galaksija BASIC|Galaksija BASIC]]===
<syntaxhighlight lang="basic">
10 PRINT "Year";: INPUT Y
20 PRINT "Month";: INPUT M
30 PRINT "Day";: INPUT D
40 IF M < 3 THEN Y = Y - 1: M = M + 12
50 M = M - 2
60 W = (D + INT(31 * M / 12) + Y + INT(Y / 4) - INT(Y / 100) + INT(Y / 400))
70 W = W - INT(W / 7) * 7
80 PRINT "Weekday: "; W
90 STOP
</syntaxhighlight>
===[[w:GW-BASIC|GW-BASIC]] и совместимые диалекты===
<syntaxhighlight lang="basic">
10 INPUT "Year", Y%: INPUT "Month", M%: INPUT "Day", D%
20 IF M% < 3 THEN Y% = Y% - 1: M% = M% + 10: ELSE M% = M% - 2
30 PRINT "Weekday: "; (D% + 31 * M% \ 12 + Y% + Y% \ 4 - Y% \ 100 + Y% \ 400) MOD 7
</syntaxhighlight>
===[[w:QuickBasic|QuickBasic]] версий < 4.0, [[w:Turbo Basic|Turbo Basic]]===
<syntaxhighlight lang="basic">
DEF FNWD%(Y%, M%, D%)
IF M% < 3 THEN
Y% = Y% - 1
M% = M% + 10
ELSE
M% = M% - 2
END IF
FNWD% = (D% + 31 * M% \ 12 + Y% + Y% \ 4 - Y% \ 100 + Y% \ 400) MOD 7
END DEF
</syntaxhighlight>
===[[w:PowerBASIC|PowerBASIC]], [[w:QBASIC|QBASIC]], [[w:QuickBasic|QuickBasic]] версий 4.X, [[w:Visual Basic|Visual Basic]]===
<syntaxhighlight lang="vb">
Function Weekday(year As Integer, month As Integer, day As Integer) As Integer
Dim y As Integer, m As Integer
If month < 3 Then
y = year - 1
m = month + 10
Else
y = year
m = month - 2
End If
Weekday = (day + 31 * m \ 12 + y + y \ 4 - y \ 100 + y \ 400) Mod 7
End Function
</syntaxhighlight>
'''Примечание:''' Параметры в <code>Sub</code> и <code>Function</code> передаются по ссылке, и изменение значений <code>year</code> и <code>month</code> внутри функции могло бы иметь побочные эффекты в вызывающей программе. Для предотвращения этого использованы локальные переменные <code>y</code> и <code>m</code>.
===[[w:Visual_Basic_.NET|Visual Basic .NET]]===
<syntaxhighlight lang="vb">
Function Weekday(ByVal year As UShort, ByVal month As Byte, ByVal day As Byte) As Byte
If month < 3 Then
year -= 1
month += 10
Else
month -= 2
End If
Return (day + 31 * month \ 12 + year + year \ 4 - year \ 100 + year \ 400) Mod 7
End Function
</syntaxhighlight>
==[[Язык Си в примерах|C]], [[C++]]==
<syntaxhighlight lang="C">
typedef unsigned short Year;
typedef unsigned char Month;
typedef unsigned char Day;
typedef unsigned char Weekday;
Weekday weekday(Year year, Month month, Day day) {
if (month < 3u) {
--year;
month += 10u;
} else
month -= 2u;
return (Weekday)((day + 31u * month / 12u + year + year / 4u - year / 100u + year / 400u) % 7u);
}
</syntaxhighlight>
==[[w:C_Sharp|C#]]==
<syntaxhighlight lang="csharp">
static byte Weekday(ushort year, byte month, byte day) {
if (month < 3u) {
--year;
month += 10u;
} else
month -= 2u;
return (byte)(((ushort)day + 31u * (ushort)month / 12u + year + year / 4u - year / 100u + year / 400u) % 7u);
}
</syntaxhighlight>
==[[w:Паскаль (язык программирования)|Pascal]], [[Delphi]]==
<syntaxhighlight lang="Pascal">
type TYear = Word;
type TMonth = 1..12;
type TDay = 1..31;
type TWeekday = 0..6;
function Weekday(year: TYear; month: TMonth; day: TDay): TWeekday;
begin
if month < 3 then
begin
year := year - 1;
month := month + 10
end
else
month := month - 2;
Weekday := (day + 31 * month div 12 + year + year div 4 - year div 100 + year div 400) mod 7
end;
</syntaxhighlight>
==[[w:Go (язык программирования)|Go]]==
<syntaxhighlight lang="Go">
type Year = uint16
type Month = uint8
type Day = uint8
type Weekday = uint8
func weekday(year Year, month Month, day Day) Weekday {
if month < 3 {
year--
month += 10
} else {
month -= 2
}
return Weekday((Year(day) + 31 * Year(month) / 12 + year + year / 4 - year / 100 + year / 400) % 7)
}
</syntaxhighlight>
==[[Java]]==
<syntaxhighlight lang="java">
static byte weekday(short year, byte month, byte day) {
if (month < 3) {
--year;
month += 10;
} else
month -= 2;
return (byte)(((short)day + 31 * (short)month / 12 + year + year / 4 - year / 100 + year / 400) % 7);
}
</syntaxhighlight>
==[[JavaScript]]==
<syntaxhighlight lang="JavaScript">
function weekday(year, month, day) {
year = parseInt(year, 10);
month = parseInt(month, 10);
day = parseInt(day, 10);
if (month < 3) {
--year;
month += 10;
} else
month -= 2;
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7;
}
</syntaxhighlight>
==[[Microsoft Excel]]==
А2 — ячейка, содержащая дату.
<syntaxhighlight lang="html4strict">
(English): =WEEKDAY(A2;2)
(Русский): =ДЕНЬНЕД(A2;2)
</syntaxhighlight>
ЛИБО:
<syntaxhighlight lang="html4strict">
=ОКРВНИЗ(ОСТАТ((ДЕНЬ(A2)+(ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))+ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/4;1)-ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/100;1)+ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/400;1)+ОКРВНИЗ(31*(МЕСЯЦ(A2)+12*ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1)-2)/12;1));7);1)
</syntaxhighlight>
==[[w:MS SQL|MS SQL]]==
<syntaxhighlight lang="mysql ">
CREATE FUNCTION [dbo].[getDay](
@date datetime
)
RETURNS int
AS
BEGIN
declare @a int
declare @y int
declare @m int
set @a = (14 — MONTH(@date)) / 12
set @y = YEAR(@date) — @a
set @m = MONTH(@date) + 12*@a-2
return (DAY(@date) + (31 * @m) / 12 + @y + @y / 4 — @y / 100 + @y / 400) % 7
END
</syntaxhighlight>
==[[PHP]]==
<syntaxhighlight lang="PHP">
function weekday(int $year, int $month, int $day) {
if ($month < 3) {
--$year;
$month += 10;
} else
$month -= 2;
return ($day + 31 * $month / 12 + $year + $year / 4 - $year / 100 + $year / 400) % 7;
}
</syntaxhighlight>
==[[Python]]==
<syntaxhighlight lang="python">
def weekday(year: int, month: int, day: int) -> int:
if month < 3:
year -= 1
month += 10
else:
month -= 2
return (day + 31 * month // 12 + year + year // 4 - year // 100 + year // 400) % 7
</syntaxhighlight>
==[[Ruby]]==
<syntaxhighlight lang="ruby">
def weekday(year, month, day)
if month < 3
year -= 1
month += 10
else
month -= 2
end
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7
end
</syntaxhighlight>
==[[w:Rust (язык программирования)|Rust]]==
<syntaxhighlight lang="Rust">
type Year = u16;
type Month = u8;
type Day = u8;
type Weekday = u8;
fn weekday (year: Year, month: Month, day: Day) -> Weekday {
// Чтобы не делать параметры функции изменяемыми (mut),
// вычисления производятся во вложенной функции:
fn _weekday (y: Year, m: Month, d: Day) -> Weekday {
((d as Year + 31 * m as Year / 12 + y + y / 4 - y / 100 + y / 400) % 7) as Weekday
}
if month < 3 {
_weekday(year - 1, month + 10, day)
} else {
_weekday(year, month - 2, day)
}
}
</syntaxhighlight>
==[[w:Swift (язык программирования)|Swift]]==
<syntaxhighlight lang="Swift">
func weekday (year: Int, month: Int, day: Int) -> Int {
var year = year
var month = month
if month < 3 {
year -= 1
month += 10
} else {
month -= 2
}
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7
}
</syntaxhighlight>
==[[w:Cmd.exe|Командная строка Windows (cmd.exe)]]==
<syntaxhighlight lang="C">
@echo off
set /a год = %date:~6,4%
set /a месяц = %date:~3,2%
set /a число = %date:~0,2%
set /a a = ((14 - %месяц%) / 12)
set /a y = (%год% - %a%)
set /a m = (%месяц% + (12 * %a%) - 2)
set /a ДеньНедели = (((%число% + %y% + (%y% / 4) - (%y% / 100) + (%y% / 400) + ((31 * %m%) / 12))) %% 7)
echo %ДеньНедели%
</syntaxhighlight>
==[[w:Глагол (язык программирования)|Глагол]]==
<syntaxhighlight>
ЗАДАЧА ДеньНедели (год, месяц, день: УЗКЦЕЛ): УЗКЦЕЛ;
УКАЗ
ВЫБРАТЬ месяц ИЗ
1, 2: (* январь или февраль *)
год := год - 1;
месяц := месяц + 10
ИНАЧЕ
месяц := месяц - 2
КОН;
ВОЗВРАТ (день + 31 * месяц ДЕЛИТЬ 12 + год + год ДЕЛИТЬ 4 - год ДЕЛИТЬ 100 + год ДЕЛИТЬ 400) ОСТАТОК 7
КОН ДеньНедели;
</syntaxhighlight>
==Программируемые микрокалькуляторы «Электроника»==
===МК-61 / 52 / 161 / 163 / 152 / 1152===
В вычислениях участвуют только регистры стека.
<syntaxhighlight>
00. ↔ 01. 3 02. − 03. 1 04. ↔ 05. Fx<0 06. 15 07. F🔃 08. ↔ 09. F🔃
10. − 11. 1 12. 3 13. ↔ 14. F🔃 15. + 16. 3 17. 1 18. × 19. 1
20. 2 21. ÷ 22. К[x] 23. + 24. + 25. ↔ 26. 4 27. ÷ 28. К[x] 29. +
30. ↔ 31. 2 32. F10ˣ 33. ÷ 34. ↔ 35. FВx 36. К[x] 37. − 38. ↔ 39. 4
40. ÷ 41. К[x] 42. + 43. В↑ 44. В↑ 45. 7 46. ÷ 47. К[x] 48. 7 49. ×
50. − 51. С/П
</syntaxhighlight>
'''Использование:''' <год> → регистр Z, <месяц> → регистр Y, <число> → регистр X, В/О, С/П (номер дня недели на индикаторе).
==Ссылки==
* [http://algolist.manual.ru/misc/yearweek.php Примеры программ для вычисления дня недели]
i4x9n09lnzaa6dy5qg1j3sqnhszcsas
269074
269072
2026-06-10T07:34:05Z
Yevrowl
11674
/* Galaksija BASIC */
269074
wikitext
text/x-wiki
{{wikipedia|Вечный календарь}}
=Описание=
Существует довольно простой '''алгоритм вычисления дня недели''' для любой даты [[w:Григорианский календарь|григорианского календаря]], начиная с первого дня его действия — 15 октября [[w:1582|1582]] года. (Предыдущим днём было 4 октября, числа с 5 по 14 октября включительно были пропущены для устранения 11‑дневного отставания от фактической даты, накопившегося за время использования [[w:Юлианский календарь|юлианского календаря]]).
Положим, дата задана так: ''год'' — год (от 1582), ''месяц'' — номер месяца (1…12), ''число'' — число месяца (1…31, согласно числу дней в соответствующем месяце), тогда:
a = (14 − месяц) / 12
год = год − a
месяц = месяц + 12 * a − 2
ДеньНедели = (число + (31 * месяц) / 12 + год + год / 4 − год / 100 + год / 400) ОСТАТОК 7
либо, что почти то же самое:
если месяц = 1 или месяц = 2: // январь или февраль
год = год − 1
месяц = месяц + 10
иначе:
месяц = месяц − 2
всё
ДеньНедели = (число + (31 * месяц) / 12 + год + год / 4 − год / 100 + год / 400) ОСТАТОК 7
Деление производится нацело (с отбрасыванием остатка).
Результат: 0 — воскресенье, 1 — понедельник и т. д.
=Реализации=
==[[Arduino IDE]]==
<syntaxhighlight lang="C">
//==========================================================================================
//Глобальные переменные
//==========================================================================================
byte day = 7; //число
byte month = 7; //месяц
unsigned int year = 2017; //год
//===============================================================================================
// Функция деления без остатка f_div
// Я извиняюсь, но кому в здравом уме могла прийти идея написать отдельную функцию
// целочисленного деления в C или C++?
// Всем нормальным людям известно, что простое деление двух целых с помощью '/'
// в C или в C++ - есть целочисленное деление!!!!!!! Т.е. деление без остатка, если кто не понял.
//===============================================================================================
unsigned int f_div(unsigned int x, unsigned int y){
unsigned int result;
result = (x - (x % y)) / y;
return result;
}
//==========================================================================================
//Функция вычисления дня недели
//==========================================================================================
void weekday(){
// И вы с какой целью пытаетесь запихнуть результат функции типа unsigned int, который
// может принимать значения в диапазоне 0...65535 в переменную типа byte, которая по сути
// является unsigned char, т.е. 0...255. На выхлопе можно такое получить, что юлианский
// с григорианским календарем на пару кашлять будут разными битами во все стороны ))))
byte a = f_div((14 - month), 12);
// Ну и, конечно, надо понимать, что результат здесь для a всегда будет ноль (0), кроме
// января(1) и февраля(1)
unsigned int y = year - a;
byte m = month + 12 * a - 2;
unsigned int y4 = f_div(y, 4);
byte y100 = f_div(y, 100);
byte y400 = f_div(y, 400);
byte x = f_div(31 * m, 12);
byte wd = (day + y + y4 - y100 + y400 + x) % 7; //результат в переменной "wd"
}
//набирал с клавиатуры и убил вечер на тестирование - reodos
</syntaxhighlight>
==[[w:Бейсик|BASIC]]==
===Классический===
<syntaxhighlight lang="basic">
10 PRINT "Year";: INPUT Y
20 PRINT "Month";: INPUT M
30 PRINT "Day";: INPUT D
40 IF M < 3 THEN LET Y = Y - 1: LET M = M + 12
50 LET M = M - 2
60 LET W = (D + INT(31 * M / 12) + Y + INT(Y / 4) - INT(Y / 100) + INT(Y / 400))
70 LET W = W - INT(W / 7) * 7
80 PRINT "Weekday: "; W
90 END
</syntaxhighlight>
'''Примечание:''' При выполнении условия <code>M < 3</code> в строке 40 значение M увеличивается на 12, а в строке 50 уменьшается на 2, т. е. в итоге увеличивается на 10. При невыполнении же условия значение M просто уменьшается на 2. Таким образом удаётся избежать использования оператора <code>GOTO</code>.
===[[w:Galaksija BASIC|Galaksija BASIC]]===
<syntaxhighlight lang="basic">
10 PRINT "Year";: INPUT Y
20 PRINT "Month";: INPUT M
30 PRINT "Day";: INPUT D
40 IF M < 3 Y = Y - 1: M = M + 12
50 M = M - 2
60 W = (D + INT(31 * M / 12) + Y + INT(Y / 4) - INT(Y / 100) + INT(Y / 400))
70 W = W - INT(W / 7) * 7
80 PRINT "Weekday: "; W
90 STOP
</syntaxhighlight>
===[[w:GW-BASIC|GW-BASIC]] и совместимые диалекты===
<syntaxhighlight lang="basic">
10 INPUT "Year", Y%: INPUT "Month", M%: INPUT "Day", D%
20 IF M% < 3 THEN Y% = Y% - 1: M% = M% + 10: ELSE M% = M% - 2
30 PRINT "Weekday: "; (D% + 31 * M% \ 12 + Y% + Y% \ 4 - Y% \ 100 + Y% \ 400) MOD 7
</syntaxhighlight>
===[[w:QuickBasic|QuickBasic]] версий < 4.0, [[w:Turbo Basic|Turbo Basic]]===
<syntaxhighlight lang="basic">
DEF FNWD%(Y%, M%, D%)
IF M% < 3 THEN
Y% = Y% - 1
M% = M% + 10
ELSE
M% = M% - 2
END IF
FNWD% = (D% + 31 * M% \ 12 + Y% + Y% \ 4 - Y% \ 100 + Y% \ 400) MOD 7
END DEF
</syntaxhighlight>
===[[w:PowerBASIC|PowerBASIC]], [[w:QBASIC|QBASIC]], [[w:QuickBasic|QuickBasic]] версий 4.X, [[w:Visual Basic|Visual Basic]]===
<syntaxhighlight lang="vb">
Function Weekday(year As Integer, month As Integer, day As Integer) As Integer
Dim y As Integer, m As Integer
If month < 3 Then
y = year - 1
m = month + 10
Else
y = year
m = month - 2
End If
Weekday = (day + 31 * m \ 12 + y + y \ 4 - y \ 100 + y \ 400) Mod 7
End Function
</syntaxhighlight>
'''Примечание:''' Параметры в <code>Sub</code> и <code>Function</code> передаются по ссылке, и изменение значений <code>year</code> и <code>month</code> внутри функции могло бы иметь побочные эффекты в вызывающей программе. Для предотвращения этого использованы локальные переменные <code>y</code> и <code>m</code>.
===[[w:Visual_Basic_.NET|Visual Basic .NET]]===
<syntaxhighlight lang="vb">
Function Weekday(ByVal year As UShort, ByVal month As Byte, ByVal day As Byte) As Byte
If month < 3 Then
year -= 1
month += 10
Else
month -= 2
End If
Return (day + 31 * month \ 12 + year + year \ 4 - year \ 100 + year \ 400) Mod 7
End Function
</syntaxhighlight>
==[[Язык Си в примерах|C]], [[C++]]==
<syntaxhighlight lang="C">
typedef unsigned short Year;
typedef unsigned char Month;
typedef unsigned char Day;
typedef unsigned char Weekday;
Weekday weekday(Year year, Month month, Day day) {
if (month < 3u) {
--year;
month += 10u;
} else
month -= 2u;
return (Weekday)((day + 31u * month / 12u + year + year / 4u - year / 100u + year / 400u) % 7u);
}
</syntaxhighlight>
==[[w:C_Sharp|C#]]==
<syntaxhighlight lang="csharp">
static byte Weekday(ushort year, byte month, byte day) {
if (month < 3u) {
--year;
month += 10u;
} else
month -= 2u;
return (byte)(((ushort)day + 31u * (ushort)month / 12u + year + year / 4u - year / 100u + year / 400u) % 7u);
}
</syntaxhighlight>
==[[w:Паскаль (язык программирования)|Pascal]], [[Delphi]]==
<syntaxhighlight lang="Pascal">
type TYear = Word;
type TMonth = 1..12;
type TDay = 1..31;
type TWeekday = 0..6;
function Weekday(year: TYear; month: TMonth; day: TDay): TWeekday;
begin
if month < 3 then
begin
year := year - 1;
month := month + 10
end
else
month := month - 2;
Weekday := (day + 31 * month div 12 + year + year div 4 - year div 100 + year div 400) mod 7
end;
</syntaxhighlight>
==[[w:Go (язык программирования)|Go]]==
<syntaxhighlight lang="Go">
type Year = uint16
type Month = uint8
type Day = uint8
type Weekday = uint8
func weekday(year Year, month Month, day Day) Weekday {
if month < 3 {
year--
month += 10
} else {
month -= 2
}
return Weekday((Year(day) + 31 * Year(month) / 12 + year + year / 4 - year / 100 + year / 400) % 7)
}
</syntaxhighlight>
==[[Java]]==
<syntaxhighlight lang="java">
static byte weekday(short year, byte month, byte day) {
if (month < 3) {
--year;
month += 10;
} else
month -= 2;
return (byte)(((short)day + 31 * (short)month / 12 + year + year / 4 - year / 100 + year / 400) % 7);
}
</syntaxhighlight>
==[[JavaScript]]==
<syntaxhighlight lang="JavaScript">
function weekday(year, month, day) {
year = parseInt(year, 10);
month = parseInt(month, 10);
day = parseInt(day, 10);
if (month < 3) {
--year;
month += 10;
} else
month -= 2;
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7;
}
</syntaxhighlight>
==[[Microsoft Excel]]==
А2 — ячейка, содержащая дату.
<syntaxhighlight lang="html4strict">
(English): =WEEKDAY(A2;2)
(Русский): =ДЕНЬНЕД(A2;2)
</syntaxhighlight>
ЛИБО:
<syntaxhighlight lang="html4strict">
=ОКРВНИЗ(ОСТАТ((ДЕНЬ(A2)+(ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))+ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/4;1)-ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/100;1)+ОКРВНИЗ((ГОД(A2)-ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1))/400;1)+ОКРВНИЗ(31*(МЕСЯЦ(A2)+12*ОКРВНИЗ((14-МЕСЯЦ(A2))/12;1)-2)/12;1));7);1)
</syntaxhighlight>
==[[w:MS SQL|MS SQL]]==
<syntaxhighlight lang="mysql ">
CREATE FUNCTION [dbo].[getDay](
@date datetime
)
RETURNS int
AS
BEGIN
declare @a int
declare @y int
declare @m int
set @a = (14 — MONTH(@date)) / 12
set @y = YEAR(@date) — @a
set @m = MONTH(@date) + 12*@a-2
return (DAY(@date) + (31 * @m) / 12 + @y + @y / 4 — @y / 100 + @y / 400) % 7
END
</syntaxhighlight>
==[[PHP]]==
<syntaxhighlight lang="PHP">
function weekday(int $year, int $month, int $day) {
if ($month < 3) {
--$year;
$month += 10;
} else
$month -= 2;
return ($day + 31 * $month / 12 + $year + $year / 4 - $year / 100 + $year / 400) % 7;
}
</syntaxhighlight>
==[[Python]]==
<syntaxhighlight lang="python">
def weekday(year: int, month: int, day: int) -> int:
if month < 3:
year -= 1
month += 10
else:
month -= 2
return (day + 31 * month // 12 + year + year // 4 - year // 100 + year // 400) % 7
</syntaxhighlight>
==[[Ruby]]==
<syntaxhighlight lang="ruby">
def weekday(year, month, day)
if month < 3
year -= 1
month += 10
else
month -= 2
end
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7
end
</syntaxhighlight>
==[[w:Rust (язык программирования)|Rust]]==
<syntaxhighlight lang="Rust">
type Year = u16;
type Month = u8;
type Day = u8;
type Weekday = u8;
fn weekday (year: Year, month: Month, day: Day) -> Weekday {
// Чтобы не делать параметры функции изменяемыми (mut),
// вычисления производятся во вложенной функции:
fn _weekday (y: Year, m: Month, d: Day) -> Weekday {
((d as Year + 31 * m as Year / 12 + y + y / 4 - y / 100 + y / 400) % 7) as Weekday
}
if month < 3 {
_weekday(year - 1, month + 10, day)
} else {
_weekday(year, month - 2, day)
}
}
</syntaxhighlight>
==[[w:Swift (язык программирования)|Swift]]==
<syntaxhighlight lang="Swift">
func weekday (year: Int, month: Int, day: Int) -> Int {
var year = year
var month = month
if month < 3 {
year -= 1
month += 10
} else {
month -= 2
}
return (day + 31 * month / 12 + year + year / 4 - year / 100 + year / 400) % 7
}
</syntaxhighlight>
==[[w:Cmd.exe|Командная строка Windows (cmd.exe)]]==
<syntaxhighlight lang="C">
@echo off
set /a год = %date:~6,4%
set /a месяц = %date:~3,2%
set /a число = %date:~0,2%
set /a a = ((14 - %месяц%) / 12)
set /a y = (%год% - %a%)
set /a m = (%месяц% + (12 * %a%) - 2)
set /a ДеньНедели = (((%число% + %y% + (%y% / 4) - (%y% / 100) + (%y% / 400) + ((31 * %m%) / 12))) %% 7)
echo %ДеньНедели%
</syntaxhighlight>
==[[w:Глагол (язык программирования)|Глагол]]==
<syntaxhighlight>
ЗАДАЧА ДеньНедели (год, месяц, день: УЗКЦЕЛ): УЗКЦЕЛ;
УКАЗ
ВЫБРАТЬ месяц ИЗ
1, 2: (* январь или февраль *)
год := год - 1;
месяц := месяц + 10
ИНАЧЕ
месяц := месяц - 2
КОН;
ВОЗВРАТ (день + 31 * месяц ДЕЛИТЬ 12 + год + год ДЕЛИТЬ 4 - год ДЕЛИТЬ 100 + год ДЕЛИТЬ 400) ОСТАТОК 7
КОН ДеньНедели;
</syntaxhighlight>
==Программируемые микрокалькуляторы «Электроника»==
===МК-61 / 52 / 161 / 163 / 152 / 1152===
В вычислениях участвуют только регистры стека.
<syntaxhighlight>
00. ↔ 01. 3 02. − 03. 1 04. ↔ 05. Fx<0 06. 15 07. F🔃 08. ↔ 09. F🔃
10. − 11. 1 12. 3 13. ↔ 14. F🔃 15. + 16. 3 17. 1 18. × 19. 1
20. 2 21. ÷ 22. К[x] 23. + 24. + 25. ↔ 26. 4 27. ÷ 28. К[x] 29. +
30. ↔ 31. 2 32. F10ˣ 33. ÷ 34. ↔ 35. FВx 36. К[x] 37. − 38. ↔ 39. 4
40. ÷ 41. К[x] 42. + 43. В↑ 44. В↑ 45. 7 46. ÷ 47. К[x] 48. 7 49. ×
50. − 51. С/П
</syntaxhighlight>
'''Использование:''' <год> → регистр Z, <месяц> → регистр Y, <число> → регистр X, В/О, С/П (номер дня недели на индикаторе).
==Ссылки==
* [http://algolist.manual.ru/misc/yearweek.php Примеры программ для вычисления дня недели]
juobo2p9dciyumnguvo1q0wget0z5ol