Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit31208c1

Browse files
committed
Cleanup and fixes for F# BigInteger to bring it closer to BCL BigInteger behavior. Addresses bugsdotnet#105,dotnet#106,dotnet#107,dotnet#108,dotnet#109,dotnet#111, anddotnet#112. (changeset 1304009)
1 parent0030835 commit31208c1

File tree

3 files changed

+102
-32
lines changed

3 files changed

+102
-32
lines changed

‎src/fsharp/FSharp.Core/math/n.fs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,7 @@ module internal BigNatModule =
15621562
if0<= d&& d<=9then
15631563
build(add(mul ten acc)(embed d))(i+1)
15641564
else
1565-
raise(new System.FormatException("The value could not be parsed"))
1565+
raise(new System.FormatException(SR.GetString(SR.badFormatString)))
15661566

15671567
build(embed0)0
15681568

‎src/fsharp/FSharp.Core/math/z.fs‎

Lines changed: 100 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ namespace System.Numerics
1919
// NOTE: 0 has two repns (+1,0) or (-1,0).
2020
[<Struct>]
2121
[<CustomEquality; CustomComparison>]
22+
#if FX_ATLEAST_PORTABLE
23+
#else
2224
[<StructuredFormatDisplay("{StructuredDisplayString}I")>]
25+
#endif
2326
typeBigInteger(signInt:int,v: BigNat)=
2427

2528
static letsmallLim=4096
@@ -31,13 +34,17 @@ namespace System.Numerics
3134
if BigNatModule.isSmall n&& BigNatModule.getSmall n< smallLim
3235
then smallPosTab.[BigNatModule.getSmall n]
3336
else n
37+
3438
static memberinternalcreate(s,n)= BigInteger(s,BigInteger.nat n)
39+
3540
static memberinternalposn n= BigInteger(1,BigInteger.nat n)
36-
static memberinternalnegn n= BigInteger(-1,BigInteger.nat n)
3741

42+
static memberinternalnegn n= BigInteger(-1,BigInteger.nat n)
3843

3944
memberx.Sign=if x.IsZerothen0else signInt
45+
4046
memberx.SignInt= signInt
47+
4148
memberinternalx.V= v
4249

4350
static memberop_Equality(x:BigInteger,y:BigInteger)=
@@ -48,7 +55,12 @@ namespace System.Numerics
4855
|-1,-1-> BigNatModule.equal x.V y.V// -1.xv = -1.yv iff xv = yv
4956
|1,-1-> BigNatModule.isZero x.V&& BigNatModule.isZero y.V// 1.xv = -1.yv iff xv=0 and yv=0
5057
|-1,1-> BigNatModule.isZero x.V&& BigNatModule.isZero y.V// -1.xv = 1.yv iff xv=0 and yv=0
51-
|_-> invalidArg"x""signs should be +/- 1"
58+
|0,0->true
59+
|0,1-> BigNatModule.isZero y.V
60+
|0,-1-> BigNatModule.isZero y.V
61+
|1,0-> BigNatModule.isZero x.V
62+
|-1,0-> BigNatModule.isZero x.V
63+
|_-> invalidArg"x""signs should be +/- 1 or 0"
5264

5365
static memberop_Inequality(x:BigInteger,y:BigInteger)=not(BigInteger.op_Equality(x,y))// CA2226: OperatorsShouldHaveSymmetricalOverloads
5466

@@ -62,27 +74,41 @@ namespace System.Numerics
6274
// (a) xv=0 and yv=0, then false
6375
// (b) xv<>0, -1.xv < 0 <= 1.yv, so true
6476
// (c) yv<>0, -1.xv <= 0 < 1.yv, so true
65-
|_-> invalidArg"x""signs should be +/- 1"
77+
|0,0->false
78+
|0,1->not(BigNatModule.isZero y.V)
79+
|0,-1->false
80+
|1,0->false
81+
|-1,0->not(BigNatModule.isZero x.V)
82+
|_-> invalidArg"x""signs should be +/- 1 or 0"
6683

6784
static memberop_GreaterThan(x:BigInteger,y:BigInteger)=// Follow lt by +/- symmetry
6885
match x.SignInt,y.SignIntwith
6986
|1,1-> BigNatModule.gt x.V y.V
7087
|-1,-1-> BigNatModule.gt y.V x.V
7188
|1,-1->not(BigNatModule.isZero x.V)||not(BigNatModule.isZero y.V)
7289
|-1,1->false
73-
|_-> invalidArg"x""signs should be +/- 1"
90+
|0,0->false
91+
|0,1->false
92+
|0,-1->not(BigNatModule.isZero y.V)
93+
|1,0->not(BigNatModule.isZero x.V)
94+
|-1,0->false
95+
|_-> invalidArg"x""signs should be +/- 1 or 0"
7496

7597
static memberinternalcompare(n,nn)=if BigInteger.op_LessThan(n,nn)then-1elif BigInteger.op_Equality(n,nn)then0else1
76-
static memberinternalhash(z:BigInteger)= z.SignInt+ BigNatModule.hash(z.V)
98+
99+
static memberinternalhash(z:BigInteger)=
100+
if z.SignInt=0then1// 1 is hashcode for initialized BigInteger.Zero
101+
else z.SignInt+ BigNatModule.hash(z.V)
77102

78103
overridex.ToString()=
79104
match x.SignIntwith
80105
|1-> BigNatModule.toString x.V// positive
81106
|-1->
82107
if BigNatModule.isZero x.V
83108
then"0"// not negative infact, but zero.
84-
else"-"+ BigNatModule.toString x.V// negative
85-
|_-> invalidOp"signs should be +/- 1"
109+
else"-"+ BigNatModule.toString x.V// negative
110+
|0->"0"
111+
|_-> invalidOp"signs should be +/- 1 or 0"
86112

87113
memberx.StructuredDisplayString= x.ToString()
88114

@@ -99,15 +125,13 @@ namespace System.Numerics
99125

100126
overridex.GetHashCode()= BigInteger.hash(x)
101127

102-
103128
new(n:int)=
104129
if n>=0
105130
then BigInteger(1,BigInteger.nat(BigNatModule.ofInt32 n))
106131
elif(n= System.Int32.MinValue)
107132
then BigInteger(-1,BigInteger.nat(BigNatModule.ofInt64(-(int64 n))))
108133
else BigInteger(-1,BigInteger.nat(BigNatModule.ofInt32(-n)))
109134

110-
111135
new(n:int64)=
112136
if n>=0L
113137
then BigInteger(1,BigInteger.nat(BigNatModule.ofInt64 n))
@@ -116,9 +140,16 @@ namespace System.Numerics
116140
else BigInteger(-1,BigInteger.nat(BigNatModule.ofInt64(-n)))
117141

118142
static memberOne= one
143+
119144
static memberZero= zero
120-
static member(~-)(z:BigInteger)= BigInteger.create(-1* z.SignInt,z.V)
121-
static memberScale(k,z:BigInteger)=
145+
146+
static member(~-)(z:BigInteger)=
147+
match z.SignIntwith
148+
|0-> BigInteger.Zero
149+
| i-> BigInteger.create(-i, z.V)
150+
151+
static memberScale(k,z:BigInteger)=
152+
if z.SignInt=0then BigInteger.Zeroelse
122153
if k<0
123154
then BigInteger.create(-z.SignInt,(BigNatModule.scale(-k) z.V))// k.zsign.zv = -zsign.(-k.zv)
124155
else BigInteger.create(z.SignInt,(BigNatModule.scale k z.V))// k.zsign.zv = zsign.k.zv
@@ -132,8 +163,10 @@ namespace System.Numerics
132163
static memberinternaladdnn(nx,ny)=
133164
BigInteger.posn(BigNatModule.add nx ny)// Compute "nx + ny" to be integer
134165

135-
memberx.IsZero= BigNatModule.isZero x.V// signx.xv = 0 iff xv=0, since signx is +1,-1
166+
memberx.IsZero= x.SignInt=0|| BigNatModule.isZero x.V
167+
136168
memberx.IsOne=(x.SignInt=1)&& BigNatModule.isOne x.V// signx.xv = 1 iff signx = +1 and xv = 1
169+
137170
static member(+)(x:BigInteger,y:BigInteger)=
138171
if y.IsZerothen xelse
139172
if x.IsZerothen yelse
@@ -146,6 +179,7 @@ namespace System.Numerics
146179

147180
static member(-)(x:BigInteger,y:BigInteger)=
148181
if y.IsZerothen xelse
182+
if x.IsZerothen-yelse
149183
match x.SignInt,y.SignIntwith
150184
|1,1-> BigInteger.subnn(x.V,y.V)// 1.xv - 1.yv = (xv - yv)
151185
|-1,-1-> BigInteger.subnn(y.V,x.V)// -1.xv - -1.yv = (yv - xv)
@@ -162,7 +196,12 @@ namespace System.Numerics
162196
letm=(BigNatModule.mul x.V y.V)
163197
BigInteger.create(x.SignInt* y.SignInt,m)// xsign.xv * ysign.yv = (xsign.ysign).(xv.yv)
164198

165-
static memberDivRem(x:BigInteger,y:BigInteger,rem:BigInteger byref)=
199+
static memberDivRem(x:BigInteger,y:BigInteger,[<System.Runtime.InteropServices.Out>]rem:BigInteger byref)=
200+
if y.IsZerothen raise(new System.DivideByZeroException())
201+
if x.IsZerothen
202+
rem<- BigInteger.Zero
203+
BigInteger.Zero
204+
else
166205
letd,r= BigNatModule.divmod x.V y.V
167206
// HAVE: |x| = d.|y| + r and 0 <= r < |y|
168207
// HAVE: xv = d.yv + r and 0 <= r < yv
@@ -176,13 +215,22 @@ namespace System.Numerics
176215
static member(/)(x:BigInteger,y:BigInteger)=
177216
let mutablerem=new BigInteger(0)
178217
BigInteger.DivRem(x,y,&rem)
218+
179219
static member(%)(x:BigInteger,y:BigInteger)=
180220
let mutablerem=new BigInteger(0)
181221
BigInteger.DivRem(x,y,&rem)|> ignore; rem
182-
static memberGreatestCommonDivisor(x:BigInteger,y:BigInteger)= BigInteger.posn(BigNatModule.hcf x.V y.V)// hcf (xsign.xv,ysign.yv) = hcf (xv,yv)
222+
223+
static memberGreatestCommonDivisor(x:BigInteger,y:BigInteger)=
224+
match x.SignInt,y.SignIntwith
225+
|0,0-> BigInteger.Zero
226+
|0,_-> BigInteger.posn y.V
227+
|_,0-> BigInteger.posn x.V
228+
|_-> BigInteger.posn(BigNatModule.hcf x.V y.V)// hcf (xsign.xv,ysign.yv) = hcf (xv,yv)
183229

184230
memberx.IsNegative= x.SignInt=-1&&not(x.IsZero)// signx.xv < 0 iff signx = -1 and xv<>0
231+
185232
memberx.IsPositive= x.SignInt=1&&not(x.IsZero)// signx.xv > 0 iff signx = +1 and xv<>0
233+
186234
static memberAbs(x:BigInteger)=if x.SignInt=-1then-xelse x
187235

188236
static memberop_LessThanOrEqual(x:BigInteger,y:BigInteger)=
@@ -192,25 +240,39 @@ namespace System.Numerics
192240
|1,-1-> BigNatModule.isZero x.V&& BigNatModule.isZero y.V// 1.xv <= -1.yv,
193241
// (a) if xv=0 and yv=0 then true
194242
// (b) otherwise false, only meet at zero.
195-
243+
196244
|-1,1->true// -1.xv <= 1.yv, true
197-
|_-> invalidArg"x""signs should be +/- 1"
245+
|0,0->true
246+
|1,0-> BigNatModule.isZero x.V
247+
|-1,0->true
248+
|0,1->true
249+
|0,-1-> BigNatModule.isZero y.V
250+
|_-> invalidArg"x""signs should be +/- 1 or 0"
198251

199252
static memberop_GreaterThanOrEqual(x:BigInteger,y:BigInteger)=// Follow lte by +/- symmetry
200253
match x.SignInt,y.SignIntwith
201254
|1,1-> BigNatModule.gte x.V y.V
202255
|-1,-1-> BigNatModule.gte y.V x.V
203256
|1,-1->true
204257
|-1,1-> BigNatModule.isZero x.V&& BigNatModule.isZero y.V
205-
|_-> invalidArg"x""signs should be +/- 1"
206-
258+
|0,0->true
259+
|1,0->true
260+
|-1,0-> BigNatModule.isZero x.V
261+
|0,1-> BigNatModule.isZero y.V
262+
|0,-1->true
263+
|_-> invalidArg"x""signs should be +/- 1 or 0"
207264

208265
static memberPow(x:BigInteger,y:int32)=
209-
if y<0then invalidArg"y"(SR.GetString(SR.inputMustBeNonNegative))
210-
letyval= BigInteger(y)
211-
BigInteger.create((if BigNatModule.isZero(BigNatModule.rem yval.V BigNatModule.two)then1else x.SignInt), BigNatModule.pow x.V yval.V)
266+
if y<0then raise(new System.ArgumentOutOfRangeException("y",(SR.GetString(SR.inputMustBeNonNegative))))
267+
match x.IsZero, ywith
268+
|true,0-> BigInteger.One
269+
|true,_-> BigInteger.Zero
270+
|_->
271+
letyval= BigInteger(y)
272+
BigInteger.create((if BigNatModule.isZero(BigNatModule.rem yval.V BigNatModule.two)then1else x.SignInt), BigNatModule.pow x.V yval.V)
212273

213274
static memberop_Explicit(x:BigInteger)=
275+
if x.IsZerothen0else
214276
letu= BigNatModule.toUInt32 x.V
215277
if u<= uint32 System.Int32.MaxValuethen
216278
// Handle range [-MaxValue,MaxValue]
@@ -222,7 +284,8 @@ namespace System.Numerics
222284
else
223285
raise(System.OverflowException())
224286

225-
static memberop_Explicit(x:BigInteger)=
287+
static memberop_Explicit(x:BigInteger)=
288+
if x.IsZerothen0Lelse
226289
letu= BigNatModule.toUInt64 x.V
227290
if u<= uint64 System.Int64.MaxValuethen
228291
(* Handle range [-MaxValue,MaxValue]*)
@@ -238,17 +301,23 @@ namespace System.Numerics
238301
match x.SignIntwith
239302
|1-> BigNatModule.toFloat x.V// float (1.xv) = float (xv)
240303
|-1->-(BigNatModule.toFloat x.V)// float (-1.xv) = - float (xv)
241-
|_-> invalidArg"x""signs should be +/- 1"
304+
|0->0.
305+
|_-> invalidArg"x""signs should be +/- 1 or 0"
242306

243307
static memberParse(text:string)=
308+
if text=nullthen raise(new ArgumentNullException("text"))
309+
lettext= text.Trim()
244310
letlen= text.Length
245-
if len=0then raise(new System.FormatException("The value could not be parsed"))
246-
if text.[0..0]="-"then
247-
BigInteger.negn(BigNatModule.ofString text.[1..len-1])
248-
else
249-
BigInteger.posn(BigNatModule.ofString text)
250-
251-
memberinternalx.IsSmall= BigNatModule.isSmall(x.V)
311+
if len=0then raise(new System.FormatException(SR.GetString(SR.badFormatString)))
312+
match text.[0], lenwith
313+
|'-',1-> raise(new System.FormatException(SR.GetString(SR.badFormatString)))
314+
|'-',_-> BigInteger.negn(BigNatModule.ofString text.[1..len-1])
315+
|'+',1-> raise(new System.FormatException(SR.GetString(SR.badFormatString)))
316+
|'+',_-> BigInteger.posn(BigNatModule.ofString text.[1..len-1])
317+
|_-> BigInteger.posn(BigNatModule.ofString text)
318+
319+
memberinternalx.IsSmall= x.IsZero|| BigNatModule.isSmall(x.V)
320+
252321
static memberFactorial(x:BigInteger)=
253322
if x.IsNegativethen invalidArg"x"(SR.GetString(SR.inputMustBeNonNegative))
254323
if x.IsPositivethen BigInteger.posn(BigNatModule.factorial x.V)
@@ -257,6 +326,7 @@ namespace System.Numerics
257326
static member(~+)(n1:BigInteger)= n1
258327

259328
static memberFromInt64(x:int64)=new BigInteger(x)
329+
260330
static memberFromInt32(x:int32)=new BigInteger(x)
261331
#endif
262332

‎src/fsharp/FSharp.Core/math/z.fsi‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace System.Numerics
3636
/// Return the sign of a big integer: 0,+1 or-1
3737
member Sign: int
3838
/// Compute the ratio and remainder of two big integers
39-
static member DivRem: x:BigInteger* y:BigInteger* rem:BigInteger byref-> BigInteger
39+
static member DivRem: x:BigInteger* y:BigInteger*[<System.Runtime.InteropServices.Out>]rem:BigInteger byref-> BigInteger
4040

4141
/// This operator is for consistency when this type be used from other CLI languages
4242
static member op_LessThan: x:BigInteger* y:BigInteger-> bool

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp