Groovy(三)-数字

作者: ZJ_Rocky | 来源:发表于2017-11-30 16:43 被阅读22次

    译文:Groovy Language Documentation

    Groovy支持了不同类型的整型,小数,以及java支持的Number类型。
    整型常量
    整型常量类型和java一样

    • byte
    • char
    • short
    • int
    • long
    • java.lang.BigInteger

    你可以在声明中创建如下类型的整型数字

    // primitive types
    byte  b = 1
    char  c = 2
    short s = 3
    int   i = 4
    long  l = 5
    
    // infinite precision
    BigInteger bi =  6
    

    如果你是用def关键字来声明的,那整型数字的类型就会不同:他会被转化为能容纳这个数字数值的类型。
    整型数如下:

    def a = 1
    assert a instanceof Integer
    
    // Integer.MAX_VALUE
    def b = 2147483647
    assert b instanceof Integer
    
    // Integer.MAX_VALUE + 1
    def c = 2147483648
    assert c instanceof Long
    
    // Long.MAX_VALUE
    def d = 9223372036854775807
    assert d instanceof Long
    
    // Long.MAX_VALUE + 1
    def e = 9223372036854775808
    assert e instanceof BigInteger
    

    负数如下:

    def na = -1
    assert na instanceof Integer
    
    // Integer.MIN_VALUE
    def nb = -2147483648
    assert nb instanceof Integer
    
    // Integer.MIN_VALUE - 1
    def nc = -2147483649
    assert nc instanceof Long
    
    // Long.MIN_VALUE
    def nd = -9223372036854775808
    assert nd instanceof Long
    
    // Long.MIN_VALUE - 1
    def ne = -9223372036854775809
    assert ne instanceof BigInteger
    

    另外的非十进制数
    数字也可以用二进制,八进制,十六进制,十进制表示
    二进制数
    二进制数以0b开头

    int xInt = 0b10101111
    assert xInt == 175
    
    short xShort = 0b11001001
    assert xShort == 201 as short
    
    byte xByte = 0b11
    assert xByte == 3 as byte
    
    long xLong = 0b101101101101
    assert xLong == 2925l
    
    BigInteger xBigInteger = 0b111100100001
    assert xBigInteger == 3873g
    
    int xNegativeInt = -0b10101111
    assert xNegativeInt == -175
    

    八进制数
    八进制数是以0开头然后进阶着八进制数字

    int xInt = 077
    assert xInt == 63
    
    short xShort = 011
    assert xShort == 9 as short
    
    byte xByte = 032
    assert xByte == 26 as byte
    
    long xLong = 0246
    assert xLong == 166l
    
    BigInteger xBigInteger = 01111
    assert xBigInteger == 585g
    
    int xNegativeInt = -077
    assert xNegativeInt == -63
    

    十六进制数
    十六进制数是以0x开始紧接着十六进制数

    int xInt = 0x77
    assert xInt == 119
    
    short xShort = 0xaa
    assert xShort == 170 as short
    
    byte xByte = 0x3a
    assert xByte == 58 as byte
    
    long xLong = 0xffff
    assert xLong == 65535l
    
    BigInteger xBigInteger = 0xaaaa
    assert xBigInteger == 43690g
    
    Double xDouble = new Double('0x1.0p0')
    assert xDouble == 1.0d
    
    int xNegativeInt = -0x77
    assert xNegativeInt == -119
    

    小数
    小数类型和java是一样的

    • float
    • double
    • java.lang.BigDecimal

    你能在声明中创建如下类型的小数

    // primitive types
    float  f = 1.234
    double d = 2.345
    
    // infinite precision
    BigDecimal bd =  3.456
    

    小数是可以使用e或者E紧接着可选符号(+表示正数次方,-表示负数次方)和数字来表示指数的。

    assert 1e3  ==  1_000.0
    assert 2E4  == 20_000.0
    assert 3e+1 ==     30.0
    assert 4E-2 ==      0.04
    assert 5e-1 ==      0.5
    

    为了方便地表示更精确的小数,Groovy使用java.lang.BigDecimal来表示小数类型。另外,虽然float或者double都是支持的,但是必须是明确的类型声明,或者强制转化的,或者是带有类型后缀的。BigDecimal是默认的小数类型,接受float或者double类型作为参数的方法或者闭包也是接受BigDecimal类型的。

    注意:小数类型不能用二进制,八进制,十六进制进行表示

    带有下划线的数
    当我们书写大数的时候,肉眼很难一下子分别出哪几个数字是一组的,比如:以一千为一组,或者以一些字为一组。因为允许你加上下划线,所以你可以很容易识别出这些组:

    long creditCardNumber = 1234_5678_9012_3456L
    long socialSecurityNumbers = 999_99_9999L
    double monetaryAmount = 12_345_132.12
    long hexBytes = 0xFF_EC_DE_5E
    long hexWords = 0xFFEC_DE5E
    long maxLong = 0x7fff_ffff_ffff_ffffL
    long alsoMaxLong = 9_223_372_036_854_775_807L
    long bytes = 0b11010010_01101001_10010100_10010010
    

    数字类型后缀
    我们能通过添加指定的后缀来表示一个特定的类型(例如:二进制,八进制,十六进制),大小写均可:


    例如:
    assert 42I == new Integer('42')
    assert 42i == new Integer('42') // lowercase i more readable
    assert 123L == new Long("123") // uppercase L more readable
    assert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integer
    assert 456G == new BigInteger('456')
    assert 456g == new BigInteger('456')
    assert 123.45 == new BigDecimal('123.45') // default BigDecimal type used
    assert 1.200065D == new Double('1.200065')
    assert 1.234F == new Float('1.234')
    assert 1.23E23D == new Double('1.23E23')
    assert 0b1111L.class == Long // binary
    assert 0xFFi.class == Integer // hexadecimal
    assert 034G.class == BigInteger // octal
    

    算术操作
    虽然操作符后面才讲到,但是了解算术操作行为以及它所导致最后结果的类型是非常重要的。

    除法和次方等二元运算除外

    • byte, char, shortint之间进行二元运算得到的是int
    • 二元运算中,将long类型和其他byte, char, shortint类型进行运算得到的将是long
    • 二元运算中,将BigInteger类型与其他整型类型运算将得到BigInteger
    • 二元运算中,将BigDecimal类型与其他byte, char, short,intBigInteger类型进行运算将得到BigDecimal
    • float, doubleBigDecimal进行运算将得到double
    • 两个BigDecimal类型的数进行运算将得到BigDecimal

    下面这张表总结了这些规则:


    规则

    注意:由于Groovy的操作符重载,普通的操作符也同时适用于BigIntegerBigDecimal类型数,而不像java你必须使用特定的方法来操作。

    除法运算情况
    如果两个操作是floatdouble,那么除法运算会得到double,否则会是BigDecimal(当两个数是short, char, byte, int,long, BigIntegerBigDecimal中任意组合的),那么除法运算符//=表示除和赋值)操作的结果会是BigDecimal

    BigDecimal的除法会用divide()方法来操作,如果除法得到的结果是精确的(例如:得到的结果是在同精度范围或者倍数的情况下),或者using a MathContext with a precision of the maximum of the two operands' precision plus an extra precision of 10, and a scale of the maximum of 10 and the maximum of the operands' scale.[这个没明白啥意思]

    注意:在java中有提供intdiv()方法来进行integer 类型除法,但是在Groovy中并没有提供类似方法

    次方的情况
    次方运算是用**操作符来表示的,并且有两个数组成:一个是基数一个是指数。次方的结果取决于他的操作数和操作结果。(特别是他的结果可以用整型值来表示)

    下面是一些用于决定最终结果类型的次方运算规则:

    • 当指数是小数的时候
      1.如果结果是用Integer表示的,那么结果就会是Integer
      2.如果结果是用Long表示的,那么结果就会是Long
      3.不然就会返回Double类型的数

    • 如果指数是int类型的
      1.如果指数是负数的,那么结果就会返回相应的Integer,Long,Double类型
      2.如果指数是正数或者零
      2.1.如果基数是BigDecimal,结果就是BigDecimal
      2.2.如果基数是BigInteger,结果就是BigInteger
      2.3.如果基数是Integer,结果就是Integer,如果能存放的话,不然就会是BigInteger
      2.4.如果基数是Long,结果就是Long,如果能存放的话,不然就会是BigInteger

    你可以用下面的例子来验证规则:

    // base and exponent are ints and the result can be represented by an Integer
    assert    2    **   3    instanceof Integer    //  8
    assert   10    **   9    instanceof Integer    //  1_000_000_000
    
    // the base is a long, so fit the result in a Long
    // (although it could have fit in an Integer)
    assert    5L   **   2    instanceof Long       //  25
    
    // the result can't be represented as an Integer or Long, so return a BigInteger
    assert  100    **  10    instanceof BigInteger //  10e20
    assert 1234    ** 123    instanceof BigInteger //  170515806212727042875...
    
    // the base is a BigDecimal and the exponent a negative int
    // but the result can be represented as an Integer
    assert    0.5  **  -2    instanceof Integer    //  4
    
    // the base is an int, and the exponent a negative float
    // but again, the result can be represented as an Integer
    assert    1    **  -0.3f instanceof Integer    //  1
    
    // the base is an int, and the exponent a negative int
    // but the result will be calculated as a Double
    // (both base and exponent are actually converted to doubles)
    assert   10    **  -1    instanceof Double     //  0.1
    
    // the base is a BigDecimal, and the exponent is an int, so return a BigDecimal
    assert    1.2  **  10    instanceof BigDecimal //  6.1917364224
    
    // the base is a float or double, and the exponent is an int
    // but the result can only be represented as a Double value
    assert    3.4f **   5    instanceof Double     //  454.35430372146965
    assert    5.6d **   2    instanceof Double     //  31.359999999999996
    
    // the exponent is a decimal value
    // and the result can only be represented as a Double value
    assert    7.8  **   1.9  instanceof Double     //  49.542708423868476
    assert    2    **   0.1f instanceof Double     //  1.0717734636432956
    

    相关文章

      网友评论

        本文标题:Groovy(三)-数字

        本文链接:https://www.haomeiwen.com/subject/blmvbxtx.html