概述
1.1.5. 数字
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作为参数类型的方法或闭包中也可以接受这样的文本。
小数不能用二进制、八进制或十六进制表示。
常量中的下划线
在编写长的常量数字时,很难弄清楚一些数字是如何组合在一起的,例如使用数千个组、单词等。通过允许在数字文字中放置下划线,更容易识别这些组:
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
数字类型后缀
我们可以通过给一个后缀(见下表),大小写来强制一个数字(包括二进制、八进制和十六进制)具有特定的类型。
Type | Suffix |
---|---|
BigInteger |
|
Long |
|
Integer |
|
BigDecimal |
|
Double |
|
Float |
|
例如:
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, short 和 int之间的结果将是int类型。
- 二元运算涉及到long类型和byte, char, short , int之间的运算,结果将是long类型。
- 二元运算涉及到BigInteger和其他整数类型的运算,结果将是BigInteger。
- 二元运算涉及到BigDecimal和byte, char, short, int , BigInteger的运算,结果将是BigDecimal。
- 二元运算的对象类型在float, double 和 BigDecimal之间的结果将是double类型。
- 二元运算的对象类型在两个BigDecimal之间的结果将是BigDecimal。
以下是汇总表格:
byte | char | short | int | long | BigInteger | float | double | BigDecimal | |
---|---|---|---|---|---|---|---|---|---|
byte | int | int | int | int | long | BigInteger | double | double | BigDecimal |
char | int | int | int | long | BigInteger | double | double | BigDecimal | |
short | int | int | long | BigInteger | double | double | BigDecimal | ||
int | int | long | BigInteger | double | double | BigDecimal | |||
long | long | BigInteger | double | double | BigDecimal | ||||
BigInteger | BigInteger | double | double | BigDecimal | |||||
float | double | double | double | ||||||
double | double | double | |||||||
BigDecimal | BigDecimal |
由于Groovy的运算符重载,通常的算术运算符能与BigInteger和BigDecimal一起工作,不像Java,在那里您必须使用显式的方法来操作这些数字。
除法运算符的情况
如果一个操作数是float或double,则除法运算符/(和/=用于除法和赋值)生成一个double结果,否则生成一个bigdecimal结果(如果两个操作数都是short, char, byte, int, long, BigInteger 或 BigDecimal的任意组合)。
如果除法是精确的(即生成一个可以在相同精度和小数位数的范围内表示的结果),或者使用精度为两个操作数精度的最大值加上10个额外精度,以及最大值为10和操作数最大值的刻度的MathContext,则使用divide()方法执行bigdecimal除法。
对于Java中的整数除法,您应该使用ItdiVE()方法,因为Groovy不提供专用整数除法运算符符号。
幂运算符的情况
幂运算符由**运算符表示,有两个参数:基数和指数。幂运算的结果取决于其操作数和运算结果(特别是如果结果可以表示为整数值)。
Groovy的幂运算符操作使用以下规则来确定结果类型:
- 如果指数是一个小数值
- 如果结果能表示成Integer,那么返回Integer
- 否则,如果结果能表示成Long,那么返回Long
- 其他的情况返回Double
- 如果指数是一个整形值
- 如果指数严格为负,则如果结果值符合该类型,则返回Integer, Long 或者 Double
- 如果指数是正数或者是0
- 如果基数是BigDecimal,那么结果返回BigDecimal
- 如果基数是BigInteger,那么结果返回BigInteger
- 如果基数是Integer,那么结果返回Integer
- 如果基数是Long,并且结果在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语言规范--数字篇(三)的全部内容,希望文章能够帮你解决Groovy语言规范--数字篇(三)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复