github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/math/big/float.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file implements multi-precision floating-point numbers.
     6  // Like in the GNU MPFR library (https://www.mpfr.org/), operands
     7  // can be of mixed precision. Unlike MPFR, the rounding mode is
     8  // not specified with each operation, but with each operand. The
     9  // rounding mode of the result operand determines the rounding
    10  // mode of an operation. This is a from-scratch implementation.
    11  
    12  package big
    13  
    14  import (
    15  	"github.com/shogo82148/std/math"
    16  )
    17  
    18  // 非ゼロ有限Floatは、多精度浮動小数点数を表しますr
    19  //
    20  //	符号 × 仮数部 × 2**指数
    21  //
    22  // 0.5 <= 仮数部 < 1.0、および MinExp <= 指数 <= MaxExpとなります。
    23  // Floatはゼロ(+0、-0)または無限(+Inf、-Inf)でもあり得ます。
    24  // すべてのFloatは順序付けられており、二つのFloat xとyの順序付けは
    25  // x.Cmp(y)によって定義されます。
    26  //
    27  // 各Float値には、精度、丸めモード、および精度もあります。
    28  // 精度は、値を表現するために利用可能な仮数部ビットの最大数です。
    29  // 丸めモードは、結果が仮数部ビットに収まるようにどのように丸められるべきかを指定します、
    30  // 精度は、正確な結果に対する丸め誤差を説明します。
    31  //
    32  // 特に指定がない限り、結果として*Float変数を指定するすべての操作(セッターを含む)は、
    33  // 通常レシーバを介して([Float.MantExp] の例外を除く)、結果変数の精度と丸めモードに従って数値結果を丸めます。
    34  //
    35  // 提供された結果の精度が0(以下参照)の場合、それは丸めが行われる前に
    36  // 最大の精度値を持つ引数の精度に設定され、丸めモードは変更されません。したがって、
    37  // 結果の引数として提供される未初期化のFloatは、その精度がオペランドによって
    38  // 決定される合理的な値に設定され、そのモードはRoundingModeのゼロ値(ToNearestEven)です。
    39  //
    40  // 望ましい精度を24または53に設定し、対応する丸めモード(通常は [ToNearestEven])を使用すると、
    41  // Float操作は、正常(つまり、非正規化ではない)float32またはfloat64数に対応するオペランドに対して、
    42  // 対応するfloat32またはfloat64 IEEE-754算術と同じ結果を生成します。
    43  // 指数のアンダーフローとオーバーフローは、Floatの指数がはるかに大きな範囲を持つため、
    44  // IEEE-754とは異なる値に対して0またはInfinityを導きます。
    45  //
    46  // Floatのゼロ(未初期化)値は使用準備が整っており、
    47  // 精度0と丸めモード [ToNearestEven] で数値+0.0を正確に表します。
    48  //
    49  // 操作は常にポインタ引数(*Float)を取るのではなく、
    50  // Float値を取り、各一意のFloat値は自身の一意の*Floatポインタを必要とします。
    51  // Float値を「コピー」するには、既存の(または新しく割り当てられた)Floatを
    52  // [Float.Set] メソッドを使用して新しい値に設定する必要があります。
    53  // Floatの浅いコピーはサポートされておらず、エラーを引き起こす可能性があります。
    54  type Float struct {
    55  	prec uint32
    56  	mode RoundingMode
    57  	acc  Accuracy
    58  	form form
    59  	neg  bool
    60  	mant nat
    61  	exp  int32
    62  }
    63  
    64  // ErrNaNパニックは、IEEE-754のルールに従ってNaNになる [Float] 操作によって引き起こされます。
    65  // ErrNaNはエラーインターフェースを実装します。
    66  type ErrNaN struct {
    67  	msg string
    68  }
    69  
    70  func (err ErrNaN) Error() string
    71  
    72  // NewFloatは、精度53と丸めモード [ToNearestEven] でxに設定された新しい [Float] を割り当てて返します。
    73  // xがNaNの場合、NewFloatは [ErrNaN] でパニックを起こします。
    74  func NewFloat(x float64) *Float
    75  
    76  // 指数と精度の制限。
    77  const (
    78  	MaxExp  = math.MaxInt32
    79  	MinExp  = math.MinInt32
    80  	MaxPrec = math.MaxUint32
    81  )
    82  
    83  // RoundingModeは、[Float] 値が望ましい精度に丸められる方法を決定します。
    84  // 丸めは [Float] 値を変更する可能性があり、丸め誤差は [Float] の [Accuracy] によって説明されます。
    85  type RoundingMode byte
    86  
    87  // これらの定数は、サポートされている丸めモードを定義します。
    88  const (
    89  	ToNearestEven RoundingMode = iota
    90  	ToNearestAway
    91  	ToZero
    92  	AwayFromZero
    93  	ToNegativeInf
    94  	ToPositiveInf
    95  )
    96  
    97  // Accuracyは、[Float] 値を生成した最新の操作によって生じた丸め誤差を、
    98  // 正確な値に対して説明します。
    99  type Accuracy int8
   100  
   101  // [Float] の [Accuracy] を説明する定数。
   102  const (
   103  	Below Accuracy = -1
   104  	Exact Accuracy = 0
   105  	Above Accuracy = +1
   106  )
   107  
   108  // SetPrecはzの精度をprecに設定し、(可能な場合)zの丸められた
   109  // 値を返します。仮数部が精度の損失なしにprecビットで表現できない場合、
   110  // zの丸めモードに従って丸めが行われます。
   111  // SetPrec(0)はすべての有限値を±0にマップします;無限値は変更されません。
   112  // prec > [MaxPrec] の場合、precは [MaxPrec] に設定されます。
   113  func (z *Float) SetPrec(prec uint) *Float
   114  
   115  // SetModeはzの丸めモードをmodeに設定し、正確なzを返します。
   116  // それ以外の場合、zは変更されません。
   117  // z.SetMode(z.Mode())は、zの精度を [Exact] に設定するための安価な方法です。
   118  func (z *Float) SetMode(mode RoundingMode) *Float
   119  
   120  // Precは、xの仮数部の精度をビット単位で返します。
   121  // 結果は、|x| == 0 および |x| == Inf の場合、0になる可能性があります。
   122  func (x *Float) Prec() uint
   123  
   124  // MinPrecは、xを正確に表現するために必要な最小精度を返します
   125  // (つまり、x.SetPrec(prec)がxを丸め始める最小のprec)。
   126  // 結果は、|x| == 0 および |x| == Inf の場合、0になります。
   127  func (x *Float) MinPrec() uint
   128  
   129  // Modeは、xの丸めモードを返します。
   130  func (x *Float) Mode() RoundingMode
   131  
   132  // Accは、最も最近の操作によって生成されたxの精度を返します。
   133  // その操作が明示的に異なることを文書化していない限り。
   134  func (x *Float) Acc() Accuracy
   135  
   136  // Signは以下を返します:
   137  //
   138  //	-1 は x <   0 の場合
   139  //	 0 は x が ±0 の場合
   140  //	+1 は x >   0 の場合
   141  func (x *Float) Sign() int
   142  
   143  // MantExpはxをその仮数部と指数部に分解し、指数を返します。
   144  // 非nilのmant引数が提供された場合、その値はxの仮数部に設定され、
   145  // xと同じ精度と丸めモードを持ちます。コンポーネントは
   146  // x == mant × 2**exp、0.5 <= |mant| < 1.0を満たします。
   147  // nil引数でMantExpを呼び出すことは、レシーバの指数を効率的に取得する方法です。
   148  //
   149  // 特殊なケースは以下の通りです:
   150  //
   151  //	(  ±0).MantExp(mant) = 0、mantは   ±0に設定されます
   152  //	(±Inf).MantExp(mant) = 0、mantは ±Infに設定されます
   153  //
   154  // xとmantは同じものである可能性があり、その場合、xはその
   155  // 仮数部の値に設定されます。
   156  func (x *Float) MantExp(mant *Float) (exp int)
   157  
   158  // SetMantExpはzをmant × 2**expに設定し、zを返します。
   159  // 結果のzは、mantと同じ精度と丸めモードを持ちます。
   160  // SetMantExpは [Float.MantExp] の逆ですが、0.5 <= |mant| < 1.0を必要としません。
   161  // 特に、*[Float] 型の指定されたxに対して、SetMantExpは [Float.MantExp] と次のように関連しています:
   162  //
   163  //	mant := new(Float)
   164  //	new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0
   165  //
   166  // 特殊なケースは以下の通りです:
   167  //
   168  //	z.SetMantExp(  ±0, exp) =   ±0
   169  //	z.SetMantExp(±Inf, exp) = ±Inf
   170  //
   171  // zとmantは同じものである可能性があり、その場合、zの指数はexpに設定されます。
   172  func (z *Float) SetMantExp(mant *Float, exp int) *Float
   173  
   174  // Signbitは、xが負または負のゼロであるかどうかを報告します。
   175  func (x *Float) Signbit() bool
   176  
   177  // IsInfは、xが+Infまたは-Infであるかどうかを報告します。
   178  func (x *Float) IsInf() bool
   179  
   180  // IsIntは、xが整数であるかどうかを報告します。
   181  // ±Infの値は整数ではありません。
   182  func (x *Float) IsInt() bool
   183  
   184  // SetUint64は、zをxの(可能性のある丸められた)値に設定し、zを返します。
   185  // zの精度が0の場合、それは64に変更されます(そして丸めは影響を及ぼしません)。
   186  func (z *Float) SetUint64(x uint64) *Float
   187  
   188  // SetInt64は、zをxの(可能性のある丸められた)値に設定し、zを返します。
   189  // zの精度が0の場合、それは64に変更されます(そして丸めは影響を及ぼしません)。
   190  func (z *Float) SetInt64(x int64) *Float
   191  
   192  // SetFloat64は、zをxの(可能性のある丸められた)値に設定し、zを返します。
   193  // zの精度が0の場合、それは53に変更されます(そして丸めは影響を及ぼしません)。
   194  // xがNaNの場合、SetFloat64は [ErrNaN] でパニックを起こします。
   195  func (z *Float) SetFloat64(x float64) *Float
   196  
   197  // SetIntは、zをxの(可能性のある丸められた)値に設定し、zを返します。
   198  // zの精度が0の場合、それはx.BitLen()または64の大きい方に変更されます
   199  // (そして丸めは影響を及ぼしません)。
   200  func (z *Float) SetInt(x *Int) *Float
   201  
   202  // SetRatは、zをxの(可能性のある丸められた)値に設定し、zを返します。
   203  // zの精度が0の場合、それはa.BitLen()、b.BitLen()、または64の最大のものに変更されます;
   204  // x = a/bとします。
   205  func (z *Float) SetRat(x *Rat) *Float
   206  
   207  // SetInfは、signbitが設定されている場合はzを無限のFloat -Infに、
   208  // 設定されていない場合は+Infに設定し、zを返します。
   209  // zの精度は変わらず、結果は常に [Exact] です。
   210  func (z *Float) SetInf(signbit bool) *Float
   211  
   212  // Setは、zをxの(可能性のある丸められた)値に設定し、zを返します。
   213  // zの精度が0の場合、zを設定する前にxの精度に変更されます
   214  // (そして丸めは影響を及ぼしません)。
   215  // 丸めはzの精度と丸めモードに従って実行され、
   216  // zの精度は正確な(丸められていない)結果に対する結果のエラーを報告します。
   217  func (z *Float) Set(x *Float) *Float
   218  
   219  // Copyは、zをxと同じ精度、丸めモード、および
   220  // 精度で設定し、zを返します。zと
   221  // xが同じであっても、xは変更されません。
   222  func (z *Float) Copy(x *Float) *Float
   223  
   224  // Uint64は、xをゼロに向かって切り捨てることによって得られる符号なし整数を返します。
   225  // 0 <= x <= math.MaxUint64の場合、結果はxが整数の場合は [Exact] 、それ以外の場合は [Below] です。
   226  // x < 0の場合、結果は(0, [Above])で、x > [math.MaxUint64] の場合は([math.MaxUint64], [Below])です。
   227  func (x *Float) Uint64() (uint64, Accuracy)
   228  
   229  // Int64は、xをゼロに向かって切り捨てることによって得られる整数を返します。
   230  // [math.MinInt64] <= x <= [math.MaxInt64] の場合、結果はxが整数の場合は [Exact]、それ以外の場合は [Above](x < 0)または [Below](x > 0)です。
   231  // 結果はx < [math.MinInt64] の場合は([math.MinInt64], Above)、x > [math.MaxInt64] の場合は([math.MaxInt64], [Below])です。
   232  func (x *Float) Int64() (int64, Accuracy)
   233  
   234  // Float32は、xに最も近いfloat32の値を返します。xが小さすぎて
   235  // float32で表現できない場合(|x| < [math.SmallestNonzeroFloat32] )、結果は
   236  // (0, [Below])または(-0, [Above])となります。これはxの符号によります。
   237  // xが大きすぎてfloat32で表現できない場合(|x| > [math.MaxFloat32])、
   238  // 結果は(+Inf, [Above])または(-Inf, [Below])となります。これもxの符号によります。
   239  func (x *Float) Float32() (float32, Accuracy)
   240  
   241  // Float64は、xに最も近いfloat64の値を返します。xが小さすぎて
   242  // float64で表現できない場合(|x| < [math.SmallestNonzeroFloat64])、結果は
   243  // (0, [Below])または(-0, [Above])となります。これはxの符号によります。
   244  // xが大きすぎてfloat64で表現できない場合(|x| > [math.MaxFloat64])、
   245  // 結果は(+Inf, [Above])または(-Inf, [Below])となります。これもxの符号によります。
   246  func (x *Float) Float64() (float64, Accuracy)
   247  
   248  // Intは、xをゼロに向かって切り捨てた結果を返します。
   249  // または、xが無限大の場合はnilを返します。
   250  // 結果はx.IsInt()の場合は [Exact]、それ以外の場合はx > 0の場合は [Below]、
   251  // x < 0の場合は [Above] です。
   252  // 非nilの*[Int] 引数zが提供された場合、[Int] は結果をzに格納します。
   253  // 新しい [Int] を割り当てる代わりに。
   254  func (x *Float) Int(z *Int) (*Int, Accuracy)
   255  
   256  // Ratは、xに対応する有理数を返します。
   257  // または、xが無限大の場合はnilを返します。
   258  // 結果はxがInfでない場合は [Exact] です。
   259  // 非nilの*[Rat] 引数zが提供された場合、[Rat] は結果をzに格納します。
   260  // 新しい[Rat] を割り当てる代わりに。
   261  func (x *Float) Rat(z *Rat) (*Rat, Accuracy)
   262  
   263  // Absは、zを|x|(xの絶対値)の(可能性のある丸められた)値に設定し、zを返します。
   264  func (z *Float) Abs(x *Float) *Float
   265  
   266  // Negは、zを符号を反転したxの(可能性のある丸められた)値に設定し、zを返します。
   267  func (z *Float) Neg(x *Float) *Float
   268  
   269  // Addは、zを丸められた和x+yに設定し、zを返します。zの精度が0の場合、
   270  // 操作前にxの精度またはyの精度の大きい方に変更されます。
   271  // 丸めはzの精度と丸めモードに従って行われ、
   272  // zの精度は正確な(丸められていない)結果に対する結果のエラーを報告します。
   273  // xとyが逆の符号の無限大である場合、Addは [ErrNaN] でパニックを起こします。
   274  // その場合、zの値は未定義です。
   275  func (z *Float) Add(x, y *Float) *Float
   276  
   277  // Subは、zを丸められた差分x-yに設定し、zを返します。
   278  // 精度、丸め、および精度報告は [Float.Add] と同様です。
   279  // xとyが同じ符号の無限大である場合、Subは [ErrNaN] でパニックを起こします。
   280  // その場合、zの値は未定義です。
   281  func (z *Float) Sub(x, y *Float) *Float
   282  
   283  // Mulは、zを丸められた積x*yに設定し、zを返します。
   284  // 精度、丸め、および精度報告は [Float.Add] と同様です。
   285  // 一方のオペランドがゼロで、他方のオペランドが無限大である場合、Mulは [ErrNaN] でパニックを起こします。
   286  // その場合、zの値は未定義です。
   287  func (z *Float) Mul(x, y *Float) *Float
   288  
   289  // Quoは、zを丸められた商x/yに設定し、zを返します。
   290  // 精度、丸め、および精度報告は [Float.Add] と同様です。
   291  // 両方のオペランドがゼロまたは無限大である場合、Quoは [ErrNaN] でパニックを起こします。
   292  // その場合、zの値は未定義です。
   293  func (z *Float) Quo(x, y *Float) *Float
   294  
   295  // Cmpはxとyを比較し、次の値を返します:
   296  //
   297  //	-1 は x <  y
   298  //	 0 は x == y (これには -0 == 0, -Inf == -Inf, そして +Inf == +Inf も含まれます)
   299  //	+1 は x >  y
   300  func (x *Float) Cmp(y *Float) int