最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

比较两个数字

SEO心得admin40浏览0评论
本文介绍了比较两个数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我如何比较两个数字。任何数字。像 Int 和 Float ?我没有兴趣与复数或类似的东西比较。我只想比较那些可比较的。 Float和Int是。

假设您有:

def compareTwoNumbers [???](array:Array [???],number:???)= { array(0)>数字//这必须编译}

我写什么而不是<$ c

  • Number 。
  • T <:Number 当然必须指定抽象概念:(例如)

    隐式对象Int2IntNumericConversion扩展} 隐式对象Double2DoubleNumericConversion扩展NumericConversion [Double,Double] { def convert(d:Double):Double = d } 隐式对象Int2DoubleNumericConversion extends NumericConversion [ Int,Double] { def convert(i:Int):Double = i.toDouble }

    现在比较方法如下:

    def compareTwoNumbers1 [N1,N2,N3](n1: N1,n2:N2)(隐式conv1:NumericConversion [N1,N3], conv2:NumericConversion [N2,N3], ord:Ordering [N3]):Int = { ord compare(conv1 convert n1,conv2 convert n2)}

    用法:

    compareTwoNumbers1 [Int,Double,Double](3,8D)/ / -1

    多么可惜,我们必须明确地声明类型参数,所以我试过:

    def compareTwoNumbers2 [N3] = new { def apply [N1,N2](n1:N1,n2:N2 )(隐式conv1:NumericConversion [N1,N3], conv2:NumericConversion [N2,N3], ord:Ordering [N3]):Int = { ord compare(conv1 convert n1 ,conv2转换成n2)} }

    compareTwoNumbers2 [Double](3,8D)// -1

    不满意,所以我试过了:

    trait NumericUpperBound [Num1,Nu m2,UpperBound] 隐式对象NumericUpperBoundIDD扩展NumericUpperBound [Int,Double,Double] 隐式对象NumericUpperBoundDID扩展NumericUpperBound [Double,Int,Double]

    使用新的比较方法:

    def compareTwoNumbers3 [N1, N2,N3](n1:N1,n2:N2)(隐式nub:NumericUpperBound [N1,N2,N3], conv1:NumericConversion [N1,N3], conv2:NumericConversion [N2,N3], ord:Ordering [N3]):Int = { ord compare(conv1 convert n1,conv2 convert n2)} compareTwoNumbers3( 3,8D)// -1

    当然,必须创建所有基元的类型类。但可以灵活地将它扩展到 BigInt 等等。

    编辑

    由@wvxvw提到的提到 NumericUpperBounds 矩阵的评论激励我规避矩阵,这里是一个正在运行的示例(当前不包括 Byte 和 Short ):

    trait ==> [X,Y] extends(X => Y) object ==> { def apply [X,Y](f:X => Y):X ==> Y = { new(X ==> Y){ def apply(x:X):Y = f(x)} } } 隐式val Int2LongNumericConversion = ==> {x:Int => x.toLong} 隐式val Int2FloatNumericConversion = ==> {x:Int => x.toFloat} 隐式val Int2DoubleNumericConversion = ==> {x:Int => x.toDouble} 隐式val Long2FloatNumericConversion = ==> {x:Long => x.toFloat} 隐式val Long2DoubleNumericConversion = ==> {x:Long => x.toDouble} 隐式val Float2DoubleNumericConversion = ==> {x:Float => x.toDouble} implicit def reflexiveNumericConversion [X]:X ==> X = new(X ==> X){def apply(x:X):X = x} trait NumericUpperBound [Num1,Num2,UpperBound] implicit def reflexiveNumericUpperBound [X]:NumericUpperBound [X,X,X] = new NumericUpperBound [X,X,X] {} 隐式def inductiveNumericUpperBound1 [X,Y](implicit ev:X ==> Y): NumericUpperBound [Y,X,Y] = new NumericUpperBound [Y,X,Y] {} 隐式def inductiveNumericUpperBound2 [X,Y](隐式ev:X ==> Y):NumericUpperBound [X,Y, Y] = new NumericUpperBound [X,Y,Y] {} def compareTwoNumbers [N1,N2,N3](n1:N1,n2:N2)(隐式nub:NumericUpperBound [ N1,N2,N3], conv1:N1 ==> N3, conv2:N2 ==> N3, ord:Ordering [N3]):Int = { ord compare(n1,n2)} compareTwoNumbers(9L,13)// -1

    How do I compare two numbers. Any numbers. Like Int and Float? I'm not interested in comparing with complex numbers or anything like that. I only want to compare those, which are comparable. Float and Int are.

    Suppose you have:

    def compareTwoNumbers[???](array:Array[???], number:???) = { array(0) > number // this has to compile }

    What do I write instead of ????

    Things I've tried so far:

  • Number.
  • T <: Number
  • Numeric (Sorry, I don't understand how to use it in this situation, no examples / documentation is too poor).
  • 解决方案

    I think the main problem is the conversion of numeric types. So let´s encode that:

    trait NumericConversion[X, Y] { def convert(x: X): Y }

    Of course one have to specify that abstract concept: (for example)

    implicit object Int2IntNumericConversion extends NumericConversion[Int, Int] { def convert(i: Int): Int = i } implicit object Double2DoubleNumericConversion extends NumericConversion[Double, Double] { def convert(d: Double): Double = d } implicit object Int2DoubleNumericConversion extends NumericConversion[Int, Double] { def convert(i: Int): Double = i.toDouble }

    Now the comparing method goes as follows:

    def compareTwoNumbers1[N1, N2, N3](n1: N1, n2: N2) (implicit conv1: NumericConversion[N1, N3], conv2: NumericConversion[N2, N3], ord: Ordering[N3]): Int = { ord compare (conv1 convert n1, conv2 convert n2) }

    Usage:

    compareTwoNumbers1[Int, Double, Double](3, 8D) // -1

    What a pitty, we have to explicitly state the type parameters, so I tried:

    def compareTwoNumbers2[N3] = new { def apply[N1, N2](n1: N1, n2: N2)(implicit conv1: NumericConversion[N1, N3], conv2: NumericConversion[N2, N3], ord: Ordering[N3]): Int = { ord compare (conv1 convert n1, conv2 convert n2) } }

    That reduces to one type argument:

    compareTwoNumbers2[Double](3, 8D) // -1

    Not satisfying, so I tried this:

    trait NumericUpperBound[Num1, Num2, UpperBound] implicit object NumericUpperBoundIDD extends NumericUpperBound[Int, Double, Double] implicit object NumericUpperBoundDID extends NumericUpperBound[Double, Int, Double]

    With a new comparing method:

    def compareTwoNumbers3[N1, N2, N3](n1: N1, n2: N2) (implicit nub: NumericUpperBound[N1, N2, N3], conv1: NumericConversion[N1, N3], conv2: NumericConversion[N2, N3], ord: Ordering[N3]): Int = { ord compare (conv1 convert n1, conv2 convert n2) }

    Now it works:

    compareTwoNumbers3(3, 8D) // -1

    Of course, type classes for all primitives must be created. But it´s flexible to extend it to BigInt, etc. later on.

    EDIT

    The comment by @wvxvw which mentions a matrix of NumericUpperBounds inspired me to circumvent a matrix, here is a running example (excluding Byte and Short for the moment):

    trait ==>[X, Y] extends (X => Y) object ==> { def apply[X, Y](f: X => Y): X ==> Y = { new (X ==> Y) { def apply(x: X): Y = f(x) } } } implicit val Int2LongNumericConversion = ==> { x: Int => x.toLong } implicit val Int2FloatNumericConversion = ==> { x: Int => x.toFloat } implicit val Int2DoubleNumericConversion = ==> { x: Int => x.toDouble } implicit val Long2FloatNumericConversion = ==> { x: Long => x.toFloat } implicit val Long2DoubleNumericConversion = ==> { x: Long => x.toDouble } implicit val Float2DoubleNumericConversion = ==> { x: Float => x.toDouble } implicit def reflexiveNumericConversion[X]: X ==> X = new (X ==> X) { def apply(x: X): X = x } trait NumericUpperBound[Num1, Num2, UpperBound] implicit def reflexiveNumericUpperBound[X]: NumericUpperBound[X, X, X] = new NumericUpperBound[X, X, X] {} implicit def inductiveNumericUpperBound1[X, Y](implicit ev: X ==> Y): NumericUpperBound[Y, X, Y] = new NumericUpperBound[Y, X, Y] {} implicit def inductiveNumericUpperBound2[X, Y](implicit ev: X ==> Y): NumericUpperBound[X, Y, Y] = new NumericUpperBound[X, Y, Y] {} def compareTwoNumbers[N1, N2, N3](n1: N1, n2: N2) (implicit nub: NumericUpperBound[N1, N2, N3], conv1: N1 ==> N3, conv2: N2 ==> N3, ord: Ordering[N3]): Int = { ord compare (n1, n2) } compareTwoNumbers(9L, 13) // -1

    发布评论

    评论列表(0)

    1. 暂无评论