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