如何对有理数进行"工作"重复十进制表示?

Dav*_*idC 12 math wolfram-mathematica decimal decimal-point fractions

我已经想出如何使用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]]]
Run Code Online (Sandbox Code Playgroud)

所以

repeatingDecimal[7/31]
Run Code Online (Sandbox Code Playgroud)

正确显示重复的十进制数(此处显示为图片,以便显示OverBar).

重复显示小数

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

In[]:= repeatingDecimal[7/31]//FullForm
Out[]:= Row[List[".",OverBar["225806451612903"]]]
Run Code Online (Sandbox Code Playgroud)

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

% + 24/31
Run Code Online (Sandbox Code Playgroud)

分数加重复小数

我想增加产量:1


编辑:已清理的repeatingDecimal版本

Leonid展示了如何在例程中包装Format并提供用于添加和乘以重复小数的up值.很有帮助!我需要一些时间来适应上下值.

下面的内容基本上是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
Run Code Online (Sandbox Code Playgroud)

下表显示了一些输出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}]}]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


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

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

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]]
Run Code Online (Sandbox Code Playgroud)

重复十进制加法和乘法

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

请注意,168/961占据小数点右侧的465个位置.之后,它开始重复.结果匹配的N[168/961, 465],除了OverBar,虽然换行符出现在不同的地方.并且,正如预期的那样,这与以下内容相吻合:

digits = RealDigits[168/961]
Length[digits[[1, 1]]]
Run Code Online (Sandbox Code Playgroud)

465位数


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

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

让我们考虑以下两个新增内容

repeatingDecimal[7/31] + repeatingDecimal[24/31]
N@repeatingDecimal[7/31] + N@repeatingDecimal[24/31]
Run Code Online (Sandbox Code Playgroud)

表现在四种不同的情况:

情况1:当Reals和Integers的repeatDecimals被Format 包裹时的结果,并且up值为ON

情况1

正如所料,第一次加法产生一个整数,第二次加法产生一个小数.


情况2:当Format 没有为重复和整数的repeatDecimals 包裹但是up值为ON时的结果

案例2

FormatReals和Integers周围的包装不会影响手头的添加.


情况3:为Reals和Integers Format 缠绕的repeatDecimals 时的结果,但up值为OFF

案例3

如果upvalues为OFF,则Format阻止添加.


情况4:当Format 没有包裹在重复的十进制数和实数的结果时,结果值为OFF

案例4

如果upvalues为OFF并且Format` NOT不包含在Reals和Integers的repeatingDecimals周围,则第二个加法按预期工作.

更有理由为reals和整数的情况删除Format包装器.


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

Leo*_*rin 10

你不应该给你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]]]
Run Code Online (Sandbox Code Playgroud)

然后,您还可以将其UpValues与常用功能集成,例如:

repeatingDecimal /: Plus[left___, repeatingDecimal[q_], right___] := left + q + right;
repeatingDecimal /: Times[left___, repeatingDecimal[q_], right___] :=  left * q * right;
Run Code Online (Sandbox Code Playgroud)

然后,例如,

In[146]:= repeatingDecimal[7/31]+24/31

Out[146]= 1
Run Code Online (Sandbox Code Playgroud)

您可以将此方法扩展到您可能希望使用的其他常用功能repeatingDecimal.