12

我已经弄清楚如何使用 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[{".", OverBar@StringJoin[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}]]]], 
     OverBar@StringJoin[Map[ToString, {r}]]}];
  (* One or more non-repeating; one repeating digit *)

  a[{{nr__, r_Integer}, pt_}] := 
   Row[{StringJoin[Map[ToString, {nr}]], ".", 
     OverBar@StringJoin[Map[ToString, r]]}];
  a[RealDigits[q2]]]

所以

repeatingDecimal[7/31]

正确显示重复小数(此处显示为图片,以便出现 OverBar)。

显示重复小数

从引擎盖下看,它实际上只是一个冒名顶替者,一个重复小数的图像......

In[]:= repeatingDecimal[7/31]//FullForm
Out[]:= Row[List[".",OverBar["225806451612903"]]]

当然,它的行为不像数字:

% + 24/31

分数加重复小数

我想增加产量:1


编辑:repeatingDecimal 的清理版本

Leonid 展示了如何将 Format 包装在例程中,并为重复小数的加法和乘法提供向上值。很有帮助!我需要一些时间才能对上下值感到满意。

下面的内容基本上是 Mr.Wizard 建议的代码的简化版本。我将 OverBar 设置在每个重复数字上方以允许换行。(Row 上方的单个 OverBar 看起来更整洁,但在达到正确的屏幕边距时不会中断。)

ClearAll[repeatingDecimal]

repeatingDecimal[n_Integer | n_Real] := n

Format[repeatingDecimal[q_Rational]] := Row @ Flatten[
   {IntegerPart@q, ".", RealDigits@FractionalPart@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}]}]

在此处输入图像描述


检查解决方案:使用重复小数操作

现在让我们检查重复小数的加法和乘法:

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]]

重复十进制加法和乘法

因此,重复小数的加法和乘法可以根据需要进行。 Power似乎也可以正常工作。

请注意,168/961 占据小数点右侧的 465 位。之后,它开始重复。结果与 的结果相匹配N[168/961, 465],除了OverBar,尽管换行符出现在不同的地方。而且,正如所料,这与以下内容相吻合:

digits = RealDigits[168/961]
Length[digits[[1, 1]]]

465位


Format[] 包装器对 N[] 对重复小数求和的行为的一些影响

Mr.Wizard 建议格式包装器对于整数和实数的情况是多余的。

让我们考虑以下两个添加

repeatingDecimal[7/31] + repeatingDecimal[24/31]
N@repeatingDecimal[7/31] + N@repeatingDecimal[24/31]

在四种不同的情况下表现:

案例 1:当Format 围绕Reals 和 Integers 重复 Decimals 并且向上值为ON时的结果

情况1

正如预期的那样,第一个加法产生一个整数,第二个加法产生一个小数。


案例 2:当Format 没有围绕实数和整数重复小数但向上值打开时的结果

案例2

Reals 和 Integers的Format包装器不会影响手头的加法。


案例 3Format 围绕实数和整数的重复小数但向上值关闭时的结果

案例3

如果 upvalues 为 OFF,则Format防止发生加法。


案例 4:未Format 环绕实数和整数的重复小数且向上值关闭时的结果

案例4

如果 upvalues 是 OFF 并且 Format` NOT环绕 reals 和 Integers 的 repeatingDecimals ,则第二个添加按预期工作。

更有理由为实数和整数删除 Format 包装器。


有人对案例 3 和案例 4 的不同结果有何评论?

4

2 回答 2

11

你不应该给你的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[{".", OverBar@StringJoin[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}]]]], 
  OverBar@StringJoin[Map[ToString, {r}]]}];
(*One or more non-repeating;one repeating digit*)
a[{{nr__, r_Integer}, pt_}] := 
  Row[{StringJoin[Map[ToString, {nr}]], ".", 
   OverBar@StringJoin[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

于 2011-03-05T00:36:30.550 回答
2

这是您更新的代码的可能重构。我认为这次它有效(手指交叉)。如果您不需要颜色突出显示,则可以省略~Style~该行的其余部分。

ClearAll[repeatingDecimal];

Format[repeatingDecimal[n_Integer | n_Real]] := n;

Format[repeatingDecimal[q_Rational]] :=
 Row[{IntegerPart@q, ".", RealDigits@FractionalPart@q}] /.
  {{ nr___Integer, r_List:{} }, pt_} :>
   Row@Join[
      "0" ~Table~ {-pt},
      {nr},
      If[r === {}, {}, {OverBar@Row@r}]
      ] ~Style~ If[r === {}, Blue, If[{nr} === {}, Red, Gray]]

repeatingDecimal /:
  (h : Plus | Times)[left___, repeatingDecimal[q_], right___] :=
    h[left, q, right];

我将把这个旧版本留在这里以供参考,但我现在正在对问题社区 wiki 进行编辑。

于 2011-03-05T13:32:57.000 回答