比较两个数字 [英] Compare two numbers

查看:134
本文介绍了比较两个数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



假设您有:

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

我写什么而不是<$ c





  1. Number

  2. T <:Number 数字(对不起,我不明白在这种情况下如何使用它,没有任何示例/文档也是如此我认为主要的问题是数字类型的转换。我认为主要的问题是数字类型的转换。所以让我们编码一下:

    $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $' :Y
    }

    当然必须指定抽象概念:(例如)



    隐式对象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:

    1. Number.
    2. T <: Number
    3. 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
    

    这篇关于比较两个数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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