Groovy支持不同种类整型和十进制文本,由Java的Number类型支持。
5.1 整型类型
整型类型与Java的是一样的:
byte
char
short
int
long
java.lang.BigInteger
你可以用下面的声明创建这些类型的整数:
// 基本类型byte b = 1char c = 2short s = 3int i = 4long l = 5// 无限精度BigInteger bi = 6
如果你使用def关键字来定义可选的类型,那么整型数字的类型就是可变的: 它能自行适配到合适的类型,以便能持有那个数字。
对于正数:
def a = 1assert a instanceof Integer// Integer.MAX_VALUEdef b = 2147483647assert b instanceof Integer// Integer.MAX_VALUE + 1def c = 2147483648assert c instanceof Long// Long.MAX_VALUEdef d = 9223372036854775807assert d instanceof Long// Long.MAX_VALUE + 1def e = 9223372036854775808assert e instanceof BigInteger
同样的对于负数:
def na = -1assert na instanceof Integer// Integer.MIN_VALUEdef nb = -2147483648assert nb instanceof Integer// Integer.MIN_VALUE - 1def nc = -2147483649assert nc instanceof Long// Long.MIN_VALUEdef nd = -9223372036854775808assert nd instanceof Long// Long.MIN_VALUE - 1def ne = -9223372036854775809assert ne instanceof BigInteger
可选择的基于非10进制的表示
二进制
在Java6和之前,以及在Groovy中,数字可以用十进制,八进制和十六进制来表示, 而在Java7和Groovy2,你可以使用带有0b前缀的二进制记数法:
int xInt = 0b10101111assert xInt == 175short xShort = 0b11001001assert xShort == 201 as shortbyte xByte = 0b11assert xByte == 3 as bytelong xLong = 0b101101101101assert xLong == 2925lBigInteger xBigInteger = 0b111100100001assert xBigInteger == 3873gint xNegativeInt = -0b10101111assert xNegativeInt == -175
八进制
八进制用0开头,后面跟八进制数字的经典模式来指定的。
int xInt = 077assert xInt == 63short xShort = 011assert xShort == 9 as shortbyte xByte = 032assert xByte == 26 as bytelong xLong = 0246assert xLong == 166lBigInteger xBigInteger = 01111assert xBigInteger == 585gint xNegativeInt = -077assert xNegativeInt == -63
十六进制
十六进制用0x开头,后面跟十六进制数字的经典模式来指定的。
int xInt = 0x77assert xInt == 119short xShort = 0xaaassert xShort == 170 as shortbyte xByte = 0x3aassert xByte == 58 as bytelong xLong = 0xffffassert xLong == 65535lBigInteger xBigInteger = 0xaaaaassert xBigInteger == 43690gDouble xDouble = new Double('0x1.0p0')assert xDouble == 1.0dint xNegativeInt = -0x77assert xNegativeInt == -119
5.2 小数
小数类型与Java的一样:
float
double
java.lang.BigDecimal
你可以用以下声明来创建这些小数类型数字:
// primitive typesfloat f = 1.234double d = 2.345// infinite precisionBigDecimal bd = 3.456
小数可以使用指数,使用e or E的指数表示符,后跟一个可选的符号,和一个整数表示指数值:
assert 1e3 == 1_000.0assert 2E4 == 20_000.0assert 3e+1 == 30.0assert 4E-2 == 0.04assert 5e-1 == 0.5
为了方便地进行精确的小数的计算,Groovy选择用java.lang.BigDecimal为小数的类型。 此外,无论是float 和 double都是被支持的, 但需要一个显示的类型声明,类型强制或后缀。 即使BigDecimal的是默认的小数类型,但这样的小数是可被用在以float 或 double作为参数的方法或闭包中的。
小数不能使用二进制,八进制或十六进制表示形式来表示。 |
5.3 在数字中的下划线
当在输入一个很长的数字是,是很难看清楚这些数字的, 通过容许在数字之间输入下划线来分组,这样可以更容易分清楚这些数字:
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
5.4 Number类型的后缀
我们可以用指定后缀(看下表)的方式强制指定一个数字的类型(包括二进制,八进制和十六进制),而这些后缀是不区分大小写的。
类型 | 后缀 |
---|---|
BigInteger | G or g |
Long | L or l |
Integer | I or i |
BigDecimal | G or g |
Double | D or d |
Float | F or f |
例子:
assert 42I == new Integer('42')assert 42i == new Integer('42') // lowercase i more readableassert 123L == new Long("123") // uppercase L more readableassert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integerassert 456G == new BigInteger('456')assert 456g == new BigInteger('456')assert 123.45 == new BigDecimal('123.45') // default BigDecimal type usedassert 1.200065D == new Double('1.200065')assert 1.234F == new Float('1.234')assert 1.23E23D == new Double('1.23E23')assert 0b1111L.class == Long // binaryassert 0xFFi.class == Integer // hexadecimalassert 034G.class == BigInteger // octal
5.5 算术运算
虽然操作符将会在后面详细介绍,但讨论算术运算符的行为和运算结果的类型也是非常重要的。
除了除法和指数这两个二元操作符外(后面将会介绍),
byte, char, short 和 int之间的二元运算结果将会是int
涉及到long 与 byte, char, short 和 int 的结果将会是 long
涉及到 BigInteger 和其他整型类型的结果将会是BigInteger
float, double 和 BigDecimal 之间二元操作的结果将会是 double
两个BigDecimal之间的二元操作结果将会是BigDecimal
下面的表格总结了这些规则:
byte | char | short | int | long | BigInteger | float | double | BigDecimal | |
---|---|---|---|---|---|---|---|---|---|
byte | int | int | int | int | long | BigInteger | double | double | double |
char | int | int | int | long | BigInteger | double | double | double | |
short | int | int | long | BigInteger | double | double | double | ||
int | int | long | BigInteger | double | double | double | |||
long | long | BigInteger | double | double | double | ||||
BigInteger | BigInteger | double | double | double | |||||
float | double | double | double | ||||||
double | double | double | |||||||
BigDecimal | BigDecimal |
得益于Groovy的操作符重载,常用的算术运算符一样可以用于BigInteger 和 BigDecimal之间,而不用好像Java那样你必须使用显式方法来操作这些数字。 |
5.5.1 除法运算符的情况
如果其中一个操作数是float或double的话,除法运算/ (和 /= 执行除法和指定)的结果将会是double,其他的都会是BigDecimal (当操作数是short, char, byte, int, long,BigInteger或BigDecimal之间的任意组合)。
BigDecimal division is performed with the divide() method if the division is exact (ie. yielding a result that can be represented within the bounds of the same precision and scale), or 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()方法,而Groovy中并没有提供专用的整数除法运算符。 |
5.5.2 幂运算的情况下
幂运算是用**操作符表示,该操作符带有两个参数:底数和指数。 幂运算的结果过取决与他的操作数和运算的结果(尤其是如果结果可被表示为一个整数)
以下是Groovy的幂运算的规则,以确定结果类型:
如果指数是一个十进制值
如果结果可被表示为一个Integer,则返回一个Integer
否则,如果结果可以表示为一个Long,然后返回一个Long
否则返回一个Double
如果指数为整数
如果底数是一个BigDecimal,则返回一个BigDecimal值的结果
如果底数是一个BigInteger,然后返回一个BigInteger结果值
如果底数是一个整数,而且结果可以放进一个Integer类型的话,就返回Integer,否则返回一个BigInteger
如果底数是一个Long,而且结果可以放进一个Long类型的话,就返回Long,否则返回一个BigInteger
当指数为负,则返回一个Integer,Long或Double,这取决与结果值是否合适那个类型
如果该指数是正数或零
我们可以用一些举例来说明这些规则:
// 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