接受两个参数均为bigints的F#Power问题 [英] F# Power issues which accepts both arguments to be bigints

查看:90
本文介绍了接受两个参数均为bigints的F#Power问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试F#.在Internet上找到的文章很有帮助,但是作为C#程序员,有时我会遇到我的解决方案会有所帮助的情况,但没有或只是部分帮助.

I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.

所以我对F#缺乏了解(很可能是编译器的工作方式),可能是我有时完全不知所措的原因.

So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.

例如,我编写了一个C#程序来确定完美数字.它使用欧几里得证明的已知形式,可以由梅森素数2p-1(2p-1)形成一个完美数(其中2p-1是素数,p表示幂).

For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).

由于F#的帮助表明'**'可用于计算幂,但使用浮点数,因此我尝试使用位移运算符(<<<)创建一个简单函数(请注意,已编辑此代码以指出需要):

Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):

 let PowBitShift (y:int32) = 1 <<< y;;

但是,在运行测试并寻求性能改进时,我还尝试了一种使用Miranda(也是一种功能编程语言)的形式,该形式使用递归和模式匹配器来计算功效.我的主要好处是我可以将变量 y 用作64位整数,这对于标准的bitshift运算符而言是不可能的.

However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.

    let rec Pow (x : int64) (y : int64) = 
    match y with
        | 0L -> 1L
        | y -> x * Pow x (y - 1L);;

事实证明,此功能实际上更快,但是我(至今)无法理解原因.也许这不是一个理智的问题,但我仍然很好奇.

It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.

秒数问题是,当计算完美数时,您会遇到这样一个事实,即int64在找到第9个完美数(由31的幂形成)后,无法显示大数相交.我正在尝试确定您是否可以使用BigInteger对象(或bigint类型),但是在这里,我对F#的了解使我有点受阻.是否可以创建一个接受两个参数均为bigints的幂函数?

The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?

我目前有这个:

let rec PowBigInt (x : bigint) (y : bigint) = 
    match y with
        | bigint.Zero -> 1I
        | y -> x * Pow x (y - 1I);;

但是会抛出一个错误,指出bigint.Zero未定义.所以我在那里也做错了. 0I不被接受作为替换,因为它会出现此错误:

But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:

Non-primitive numeric literal constants cannot be used in pattern matches because they    
can be mapped to multiple different types through the use of a NumericLiteral module.  
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the 
end of the match clause.    

但是模式匹配器不能使用'when'语句.还有其他解决方案吗?

But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?

在此先感谢您,请原谅我的冗长帖子.我只是想尽我所能表达我的挑战".

Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.

推荐答案

我不明白为什么您需要y成为int64bigint.根据此链接,已知的最大梅森编号是带有p = 43112609的数字,其中的确在int的范围内.

I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.

y作为整数,可以使用标准运算符pown : ^T -> int -> ^T代替,因为:

Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:

let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y

关于模式匹配bigint的问题,错误消息非常清楚地表明您可以通过when防护使用模式匹配:

Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:

let rec PowBigInt x y = 
    match y with
    | _ when y = 0I -> 1I
    | _ -> x * PowBigInt x (y - 1I)

这篇关于接受两个参数均为bigints的F#Power问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆