z.fs 2.9 KB
Newer Older
1
// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
L
latkin 已提交
2 3 4

#nowarn "44" // This construct is deprecated. This function is for use by compiled F# code and should not be used directly

5
namespace Microsoft.FSharp.Math
6

7 8 9 10 11 12 13
// Deliberately left empty
//
//  FSharp.Core previously exposed the namespace Microsoft.FSharp.Math even though there were no types in it.
//  This retains that.
//  Existing programs could, and did contain the line:
//  open FSharp.Math
//
L
latkin 已提交
14 15 16

namespace Microsoft.FSharp.Core

17
type bigint = System.Numerics.BigInteger
L
latkin 已提交
18

19 20 21 22 23 24
open System
open System.Diagnostics.CodeAnalysis
open System.Globalization
open Microsoft.FSharp.Core.Operators
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
open System.Numerics
L
latkin 已提交
25

26 27
[<AutoOpen>]
module NumericLiterals =
L
latkin 已提交
28

D
Don Syme 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    module NumericLiteralI =

        let tab64 = new System.Collections.Generic.Dictionary<int64, obj>()
        let tabParse = new System.Collections.Generic.Dictionary<string, obj>()

        let FromInt64Dynamic (value: int64) : obj =
            lock tab64 (fun () ->
                let mutable res = Unchecked.defaultof<_>
                let ok = tab64.TryGetValue(value, &res)

                if ok then
                    res
                else
                    res <- BigInteger(value)
                    tab64.[value] <- res
                    res)

        let inline get32 (x32: int32) =
            FromInt64Dynamic(int64 x32)

        let inline isOX s =
            not (System.String.IsNullOrEmpty(s))
            && s.Length > 2
            && s.[0] = '0'
            && s.[1] = 'x'

        let FromZero () : 'T =
            (get32 0 :?> 'T) when 'T: BigInteger = BigInteger.Zero

        let FromOne () : 'T =
            (get32 1 :?> 'T) when 'T: BigInteger = BigInteger.One

        let FromInt32 (value: int32) : 'T =
            (get32 value :?> 'T) when 'T: BigInteger = new BigInteger(value)

        let FromInt64 (value: int64) : 'T =
            (FromInt64Dynamic value :?> 'T) when 'T: BigInteger = new BigInteger(value)

        let getParse s =
            lock tabParse (fun () ->
                let mutable res = Unchecked.defaultof<_>
                let ok = tabParse.TryGetValue(s, &res)

                if ok then
                    res
                else
                    let v =
                        if isOX s then
                            BigInteger.Parse(s.[2..], NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture)
                        else
                            BigInteger.Parse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)

                    res <- v
                    tabParse.[s] <- res
                    res)

        let FromStringDynamic (text: string) : obj =
86
            getParse text
L
latkin 已提交
87

D
Don Syme 已提交
88 89
        let FromString (text: string) : 'T =
            (FromStringDynamic text :?> 'T) when 'T: BigInteger = getParse text