Как я могу сделать "рабочее" повторяющееся десятичное представление рационального числа?
Я выяснил, как отображать повторяющуюся часть повторяющегося десятичного слова с помощью OverBar.
repeatingDecimal
фактически не работает как повторяющееся десятичное число. Я хотел бы сделать вариацию, которая выглядит и ведет себя как повторяющееся десятичное число.
Вопрос
Как я могу сделать повторяющееся десятичное представление (возможно, используя Interpretation[]
)?
Фон
Пожалуйста, извините меня, если я бродят. Это мой первый вопрос, и я хотел бы понять, что я имею в виду.
Следующее будет "рисовать" повторяющееся десятичное число.
repeatingDecimal[q2_] :=
Module[{a},
a[{{nr__Integer}, pt_}] :=
StringJoin[
Map[ToString,
If[pt > -1, Insert[{nr}, ".", pt + 1],
Join[{"."}, Table["0", {Abs[pt]}], {nr}]]]];
(* repeating only *)
a[{{{r__Integer}}, pt_}] :=
Row[{".", [email protected][Map[ToString, {r}]]}];
(* One or more non-repeating;
more than one repeating digit KEEP IN THIS ORDER!! *)
a[{{nr__, {r__}}, pt_}] :=
Row[{StringJoin[
Map[ToString,
If[pt > -1, Insert[{nr}, ".", pt + 1],
Join[{"."}, Table["0", {Abs[pt]}], {nr}]]]],
[email protected][Map[ToString, {r}]]}];
(* One or more non-repeating; one repeating digit *)
a[{{nr__, r_Integer}, pt_}] :=
Row[{StringJoin[Map[ToString, {nr}]], ".",
[email protected][Map[ToString, r]]}];
a[RealDigits[q2]]]
Итак,
repeatingDecimal[7/31]
отображает повторяющееся десятичное значение (показано здесь как изображение, чтобы появилось OverBar).
![Repeating decimal displayed]()
Глядя под капот, это действительно просто самозванец, изображение повторяющегося десятичного...
In[]:= repeatingDecimal[7/31]//FullForm
Out[]:= Row[List[".",OverBar["225806451612903"]]]
Конечно, он не ведет себя как число:
% + 24/31
![fraction plus repeating decimal]()
Я хотел бы добавить к урону: 1
Изменить: очищенная версия repeatingDecimal
Леонид показал, как обернуть формат вокруг подпрограммы и поставить вверх-значения для добавления и умножения повторяющихся десятичных знаков. Очень полезно! Потребуется некоторое время для меня, чтобы быть в курсе значений вверх и вниз.
Ниже приведена упрощенная версия кода, предложенная Mr.Wizard. Я устанавливал OverBar над каждой повторяющейся цифрой, чтобы разрешить прерывание строки. (Один OverBar выше Row выглядит более аккуратным, но не может сломаться, когда достигнут правый край экрана.)
ClearAll[repeatingDecimal]
repeatingDecimal[n_Integer | n_Real] := n
Format[repeatingDecimal[q_Rational]] := Row @ Flatten[
{[email protected], ".", [email protected]@q} /.
{{nr___Integer, r_List: {}}, pt_} :> {Table[0, {-pt}], nr, OverBar /@ r}
]
repeatingDecimal[q_] + x_ ^:= q + x
repeatingDecimal[q_] * x_ ^:= q * x
repeatingDecimal[q_] ^ x_ ^:= q ^ x
В приведенной ниже таблице показан вывод из repeatingDecimal
:
n1 = 1; n2 = 15; ClearAll[i, k, r];
TableForm[Table[repeatingDecimal[i/j], {i, n1, n2}, {j, n1, n2}],
TableHeadings -> {None, Table[("r")/k, {k, n1, n2}]}]
![enter image description here]()
Проверка решения: Работа с повторяющимися десятичными знаками
Теперь проверяем сложение и умножение повторяющихся десятичных знаков:
a = repeatingDecimal[7/31];
b = repeatingDecimal[24/31];
Print["a = ", a]
Print["b = ", b]
Print["a + b = ", a, " + ", b, " = ", a + b]
Print["7/31 \[Times] 24/31 = " , (7/31)* (24/31)]
Print["a\[Times]b = ", a*b, " = \n", repeatingDecimal[a*b]]
Print[N[168/961, 465]]
![repeating decimal addition and multiplication]()
Таким образом, добавление и умножение повторяющихся десятичных знаков работают по желанию. Power
также работает нормально.
Обратите внимание, что 168/961 занимает 465 мест справа от десятичной точки. После этого он начинает повторяться. Результаты совпадают с результатами N[168/961, 465]
, за исключением OverBar
, хотя разрывы строк происходят в разных местах. И, как и следовало ожидать, это приводит к следующему:
digits = RealDigits[168/961]
Length[digits[[1, 1]]]
![465 digits]()
Некоторые эффекты оболочки Format [] по поведению N [] при суммировании повторяющихся десятичных знаков
Mr.Wizard предположил, что оболочка Формат является излишней для случаев целых чисел и реалов.
Рассмотрим, как следующие два дополнения
repeatingDecimal[7/31] + repeatingDecimal[24/31]
[email protected][7/31] + [email protected][24/31]
ведут себя в четырех разных случаях:
Случай 1: результаты, когда Format
завернутый вокруг повторенияDecimals для значений Reals и Integer и значений ВКЛ
![Case 1]()
Как и ожидалось, первое сложение дает целое число, второе - десятичное.
Случай 2: результаты, когда
Format
НЕ завернуты вокруг повторенияDecimals для реалов и целых чисел, но значения
ВКЛ
![Case 2]()
Оболочка Format
вокруг Reals и Integer не влияет на дополнения.
Случай 3: результаты, когда
Format
завернутый вокруг повторенияDecimals для реалов и целых чисел, но выше значения
ВЫКЛ
![Case 3]()
Если upvalues выключены, Format
предотвращает добавление.
Случай 4: результаты, когда
Format
НЕ завернуты вокруг повторенияDecimals для реалов и целых чисел и значений выше
ВЫКЛ
![Case 4]()
Если upvalues выключены и Format NOT wrapped вокруг повторенияDecimals для Reals и Integer, второе дополнение работает как ожидалось.
Тем более причина удаления обертки формата для случая реалов и целых чисел.
У кого-нибудь есть замечания о разных результатах в случаях 3 и 4?
Ответы
Ответ 1
Вам не следует указывать repeatingDecimal
DownVaues
, а скорее FormatValues
:
ClearAll[repeatingDecimal];
Format[repeatingDecimal[q2_]] :=
Module[{a},
a[{{nr__Integer}, pt_}] :=
StringJoin[
Map[ToString,
If[pt > -1, Insert[{nr}, ".", pt + 1],
Join[{"."}, Table["0", {Abs[pt]}], {nr}]]]];
(*repeating only*)
a[{{{r__Integer}}, pt_}] :=
Row[{".", [email protected][Map[ToString, {r}]]}];
(*One or more non-repeating;
more than one repeating digit KEEP IN THIS ORDER!!*)
a[{{nr__, {r__}}, pt_}] :=
Row[{StringJoin[
Map[ToString,
If[pt > -1, Insert[{nr}, ".", pt + 1],
Join[{"."}, Table["0", {Abs[pt]}], {nr}]]]],
[email protected][Map[ToString, {r}]]}];
(*One or more non-repeating;one repeating digit*)
a[{{nr__, r_Integer}, pt_}] :=
Row[{StringJoin[Map[ToString, {nr}]], ".",
[email protected][Map[ToString, r]]}];
a[RealDigits[q2]]]
Затем вы можете передать его также UpValues
для интеграции с общими функциями, например:
repeatingDecimal /: Plus[left___, repeatingDecimal[q_], right___] := left + q + right;
repeatingDecimal /: Times[left___, repeatingDecimal[q_], right___] := left * q * right;
Тогда, например,
In[146]:= repeatingDecimal[7/31]+24/31
Out[146]= 1
Вы можете расширить этот подход на другие общие функции, которые вы можете использовать с repeatingDecimal
.
Ответ 2
Вот возможный рефакторинг вашего обновленного кода. Я думаю, что он работает в этот раз (скрестив пальцы). Если вам не нужна подсветка цвета, вы можете оставить ~Style~
и остальную часть этой строки.
ClearAll[repeatingDecimal];
Format[repeatingDecimal[n_Integer | n_Real]] := n;
Format[repeatingDecimal[q_Rational]] :=
Row[{[email protected], ".", [email protected]@q}] /.
{{ nr___Integer, r_List:{} }, pt_} :>
[email protected][
"0" ~Table~ {-pt},
{nr},
If[r === {}, {}, {[email protected]@r}]
] ~Style~ If[r === {}, Blue, If[{nr} === {}, Red, Gray]]
repeatingDecimal /:
(h : Plus | Times)[left___, repeatingDecimal[q_], right___] :=
h[left, q, right];
Я оставлю эту более старую версию здесь для справки, но теперь я вношу изменения в вики сообщества вопросов.