2013年8月23日 星期五
iDempiere Callout A_Tab.fireDataStatusEEvent
import org.compiere.model.MTable
import org.compiere.util.DB
import org.compiere.util.Msg
String sql = null;
// A_WindowNo A_Tab A_Field A_Value A_OldValue A_Ctx BOMQty
if (A_Value!=null && A_OldValue!=A_Value){
Integer SK_BOM_ID= (Integer)A_Tab.getValue("SK_BOM_ID");
Integer SK_BOMLine_ID= (Integer)A_Tab.getValue("SK_BOMLine_ID");
BigDecimal BOMQty=(BigDecimal) A_Value;
BigDecimal OldBOMQty=(BigDecimal) A_OldValue;
if (BOMQty==null) BOMQty=new BigDecimal(0);
if (OldBOMQty==null) OldBOMQty=new BigDecimal(0);
sql = "SELECT SUM(BOMQty) FROM SK_BOMLine WHERE SK_BOM_ID=? AND SK_BOMLine_ID <> ? ";
BigDecimal sQty = DB.getSQLValueBD (null, sql, [SK_BOM_ID,SK_BOMLine_ID] );
BigDecimal tQty = sQty .add(BOMQty);
if ( tQty.compareTo(new BigDecimal(1) ) !=0 )
A_Tab.fireDataStatusEEvent("合計不等於一","合計:"+ tQty+"不等於一", false);
// A_Tab.setValue("Description", "目前總數:"+tQty ); // +" , "+BOMQty+" , "+OldBOMQty+" , "+SK_BOM_ID+" , "+SK_BOMLine_ID);
}
result=""
IDempiere Callout 檢測目前 BOM Qty
import org.compiere.model.MTable
import org.compiere.util.DB
String sql = null;
// A_WindowNo A_Tab A_Field A_Value A_OldValue A_Ctx BOMQty
if (A_Value!=null && A_OldValue!=A_Value){
Integer SK_BOM_ID= (Integer)A_Tab.getValue("SK_BOM_ID");
Integer SK_BOMLine_ID= (Integer)A_Tab.getValue("SK_BOMLine_ID");
BigDecimal BOMQty=(BigDecimal) A_Value;
BigDecimal OldBOMQty=(BigDecimal) A_OldValue;
if (BOMQty==null) BOMQty=new BigDecimal(0);
if (OldBOMQty==null) OldBOMQty=new BigDecimal(0);
sql = "SELECT SUM(BOMQty) FROM SK_BOMLine WHERE SK_BOM_ID=? AND SK_BOMLine_ID <> ? ";
BigDecimal sQty = DB.getSQLValueBD (null, sql, [SK_BOM_ID,SK_BOMLine_ID] );
BigDecimal tQty = sQty .add(BOMQty);
A_Tab.setValue("Description", "目前總數:"+tQty ); // +" , "+BOMQty+" , "+OldBOMQty+" , "+SK_BOM_ID+" , "+SK_BOMLine_ID);
}
result=""
import org.compiere.util.DB
String sql = null;
// A_WindowNo A_Tab A_Field A_Value A_OldValue A_Ctx BOMQty
if (A_Value!=null && A_OldValue!=A_Value){
Integer SK_BOM_ID= (Integer)A_Tab.getValue("SK_BOM_ID");
Integer SK_BOMLine_ID= (Integer)A_Tab.getValue("SK_BOMLine_ID");
BigDecimal BOMQty=(BigDecimal) A_Value;
BigDecimal OldBOMQty=(BigDecimal) A_OldValue;
if (BOMQty==null) BOMQty=new BigDecimal(0);
if (OldBOMQty==null) OldBOMQty=new BigDecimal(0);
sql = "SELECT SUM(BOMQty) FROM SK_BOMLine WHERE SK_BOM_ID=? AND SK_BOMLine_ID <> ? ";
BigDecimal sQty = DB.getSQLValueBD (null, sql, [SK_BOM_ID,SK_BOMLine_ID] );
BigDecimal tQty = sQty .add(BOMQty);
A_Tab.setValue("Description", "目前總數:"+tQty ); // +" , "+BOMQty+" , "+OldBOMQty+" , "+SK_BOM_ID+" , "+SK_BOMLine_ID);
}
result=""
2013年8月9日 星期五
國立 [教通大學] 2013/2014 年度交換學生甄選計畫簡章
101.10.8 國際事務處主管會議通過
一、宗旨
國立 [教通大學](以下簡稱本校)為培養及拓展本校學生之國際視野,並建立選送本校學生
出國進行交換之公平甄選機制,特訂定本辦法。
二、申請資格
1. 具本校學籍,且為本校在學之正式學生(不含在職專班生),大學部學生二年級(含)以
上、研究所學生一年級(含)以上,皆可提出申請。
2. 領有臺灣獎學金、CSUCA 獎學金及本校提供獎學金之境外學生,亦可提出申請;惟台
灣獎學金及CSUCA 獎學金受獎生如出國進行交換,依相關規定須放棄受獎資格,且回
國後不得再次提出申請;凡領取交大各類獎學金之境外學生,於出國期間皆不得支領
獎學金,但可減免學雜費。
3. 具備外語檢定考試成績:凡具有效之托福、雅思、全民英檢及多益成績,或志願校接
受之第三外語檢定成績者,皆可參加校內甄選。惟通過校內甄選後,外語檢定考試之
項目及分數必須符合姊妹校規定,方可取得本校推薦生資格。
三、申請需備資料
1. 交換生申請表
2. 語言能力證明
3. 歷年成績單
4. 在學證明
5. 自傳
6. 讀書計畫
7. 推薦函(建議檢附,至多一封)
申請資料說明:
(1) 語言能力證明須為兩年內有效之成績單。已報考托福的學生,如申請時尚未收到成
績單正本,可以網路成績單代替;但需於收到正本後,繳交成績單影本,並出具正
本核驗。
於申請截止日前尚未收到成績單正本或網路成績單者,恕不接受申請。
提出多益成績者,必須繳交多益測驗(TOEIC)及多益口說與寫作測驗(TOEIC Speaking
and Writing Tests)兩項考試成績單,恕不接受以單一多益成績申請。
(2) 大學部、研究所二年級以上學生,請繳交累計至100 學年度下學期之中文歷年成
績單,須包含班/系所排名百分比。碩士班/博士班新生請繳交大學部或碩士班歷年
成績單,須包含班/系所排名百分比。
(3) 自傳及讀書計畫可以中文或英文撰寫。
(4) 讀書計畫請就志願排序第一之學校,擬訂研修計畫(含擬研修課程列表,並具體說明
修習課程的原因或對學習上的幫助)。
(5) 交換志願每生至多可填五所學校。填寫志願前請先自行確認該校是否有相關系所可
選讀,或是否以學生熟稔之語言授課,再行填寫。本處無法提供選校/系或選課諮詢,
學生於取得校內交換資格後,若因姊妹校無適合系/所或課程,導致無法進入該校交
換,學生須自行負責。
2013年8月8日 星期四
Groovy 在 iDempiere 是規則引擎最佳描述語言 Rule engine script language
Groovy 在 iDempiere 是規則引擎最佳描述語言 Rule engine script language
Groovy numbers are either decimals or integers. The 3 main types of integers are Integer, Long, and BigInteger. BigInteger has no size limit, while Integer and Long do. We can enquire their minimum and maximum values:
assert Integer.MAX_VALUE == 21,4748,3647 //at 2 billion, big enough for most uses
assert Integer.MIN_VALUE == -2,147,483,648
assert Long.MAX_VALUE == 9,223,372,036,854,775,807
assert Long.MIN_VALUE == -9,223,372,036,854,775,808
Integers will normally be the smallest type into which the value will fit (using 2's-complement representation):
assert 110.class == Integer // 正整數
assert 3000000000.class == Long // 長整數 value too large for an Integer
assert 10000000000000000000.class == BigInteger // 大整數 value too large for a Long
We can represent integers in base-10, hexadecimal, or octal notation:
//base-10 integers, positive or negative...
[ 2, -17, +987 ].each{ assert it }
//hex using leading 0x (lowercase or uppercase for a,b,c,d,e,f,x)...
[ 0xACe, 0X01ff ].each{ assert it }
//octal using leading 0...
[ 077, 01 ].each{ assert it }
We can negate hexadecimals and octals to represent negative numbers.
assert 0x7FFFFFFF.class == Integer
assert (-0x7FFFFFFF).class == Integer //we must negate using the minus sign
assert 0x80000000.class == Long
assert (-0x80000000).class == Integer
assert (-0x80000001).class == Long
We can force an integer (including hexadecimals and octals) to have a specific type by giving a suffix (I for Integer, L for Long, G for BigInteger), either uppercase or lowercase:
assert 42i.class == Integer //lowercase i more readable
assert 123L.class == Long //uppercase L more readable
assert 456g.class == BigInteger
assert 0xFFi.class == Integer
Fixed-Size Integers
The fixed-size integers, Integer and Long, each have size limits but are more efficient in calculations.
There are also the less common Byte and Short types of integer, which act like the Integer type in math operations.
assert Short.MAX_VALUE == 32767
assert Short.MIN_VALUE == -32768
assert Byte.MAX_VALUE == 127
assert Byte.MIN_VALUE == -128
def a= new Byte('34'), b= new Byte('2')
assert (a+b).class == Integer
We can enquire the bit-size of each type of fixed-size integer:
assert Integer.SIZE == 32
assert Long.SIZE == 64
assert Short.SIZE == 16
assert Byte.SIZE == 8
The class Integer can often be written int. The classes Long, Short, and Byte can each also often be written uncapitalized, ie, long, short, and byte. We can enquire these alternative (aka "primitive type") names:
assert Integer.TYPE == int
assert Long.TYPE == long
assert Short.TYPE == short
assert Byte.TYPE == byte
The fixed-size integer classes can be converted to one another:
assert 45L as Integer == 45i
assert 45L as int == 45i //example of using 'int' for Integer
assert 45L.toInteger() == 45i //alternative syntax
assert 23L.intValue() == 23i //another alternative syntax
assert 45i as Long == 45L
assert 45i as long == 45L
assert 23i.toLong() == 23L
assert 45i.longValue() == 45L
//if converted number too large for target, only lowest order bits returned...
assert 256i as Byte == 0
assert 200i as byte == -56 //...and this may result in a negative number
We can create new fixed-sized integers from strings:
assert '42'.toInteger() == 42i
assert '56'.toLong() == 56L
try{ 'moo'.toLong(); assert false }
catch(e){ assert e instanceof NumberFormatException }
assert new Integer( '45' ) == 45i
assert new Byte( '45' ) == 45 as byte
try{ new Integer( 'oink' ); assert false }
catch(e){ assert e instanceof NumberFormatException }
To convert from a fixed-size integer to a string in various bases:
//second character is the base/radix...
assert Integer.toString( 29, 16 ) == '1d'
//Long version behaves just like Integer version...
assert Long.toString( 29L, 16 ) == '1d'
//if number is negative, so is first character of returned string...
assert Integer.toString( -29, 16 ) == '-1d'
//only time result begins with zero is if it is zero...
assert Integer.toString(0) == '0'
assert Integer.toString( 29, 16 ).toUpperCase() == '1D'
//second argument defaults to 10...
assert Integer.toString( 29 ) == '29'
//Short version only accepts one parameter, only allowing base 10...
assert Short.toString( 29 as short ) == '29'
If the base/radix isn't between Character.MIN_RADIX and Character.MAX_RADIX, base 10 is used instead:
assert Integer.toString( 999, Character.MIN_RADIX - 1 ) ==
Integer.toString( 999, 10 )
assert Integer.toString( 999, Character.MAX_RADIX + 1 ) ==
Integer.toString( 999, 10 )
assert Character.MAX_RADIX == 36
//the symbols letters 0123456789abcdefghijklmnopqrstuvwxyz are used
The common bases have similar methods which always return an unsigned integer:
assert Integer.toHexString(29) == '1d' //return unsigned base-16 integer
assert Integer.toHexString(0) == '0'
assert Integer.toHexString(-17) == 'ffffffef'
assert Long.toHexString(-17L) == 'ffffffffffffffef'
//same as toString(,16) when number positive...
assert Integer.toHexString(29) == Integer.toString(29,16)
//...but different when number negative
assert Integer.toHexString(-17) != Integer.toString(-17,16)
assert Integer.toOctalString(29) == '35'
assert Integer.toOctalString(0) == '0'
assert Integer.toOctalString(-17) == '37777777757'
assert Integer.toBinaryString(29) == '11101'
We can convert a string representation to an integer, using a specified base/radix:
assert Integer.parseInt("0", 10) == 0
assert Integer.parseInt("473", 10) == 473
assert Long.parseLong("473", 10) == 473L //Long type has similarly-acting method
assert Integer.parseInt("473") == 473 //base 10 is the default base/radix
assert Integer.parseInt("-0", 10) == 0
assert Integer.parseInt("-FF", 16) == -255
assert Integer.parseInt("1100110", 2) == 102
assert Integer.parseInt("2147483647", 10) == 2147483647
assert Integer.parseInt("-2147483648", 10) == -2147483648
assert Integer.parseInt("Kona", 27) == 411787
assert Long.parseLong("Hazelnut", 36) == 1356099454469L
assert Short.parseShort("-FF", 16) == -255
A NumberFormatException may be thrown:
[ { Integer.parseInt("2147483648", 10) }, //number too large
{ Integer.parseInt("99", 8) }, //digit 9 not octal
{ Integer.parseInt("Kona", 10) }, //digits not decimal
{ Integer.parseInt("1111", Character.MIN_RADIX - 1 ) }, //radix too small
{ Integer.parseInt("1111", Character.MAX_RADIX + 1 ) }, //radix too large
{ Integer.parseInt( '@#$%' ) }, //invalid number
{ Integer.parseInt( '' ) }, //invalid number
].each{ c->
try{ c(); assert false }
catch(e){assert e instanceof NumberFormatException}
}
An alternative method name is:
assert Integer.valueOf( '12af', 16 ) == 0x12af
//same as: Integer.parseInt( '12af', 16 )
assert Long.valueOf( '123' ) == 123
//same as: Long.parseInt( '123' )
assert Short.valueOf( 027 as short ) == 027
We can convert a string to a fixed-size integer, similar to parseInt() etc, but with the radix instead indicated inside the string:
assert Integer.decode('0xff') == 0xFF
assert Integer.decode('#FF') == 0xFF
assert Long.decode('#FF') == 0xFFL //long, short, and byte also can be decoded
assert Short.decode('#FF') == 0xFF as short
assert Byte.decode('#F') == 0xF as byte
assert Integer.decode('-077') == -077
assert Integer.decode('2345') == 2345
try{ Integer.decode('7 @8'); assert false }
catch(e){ assert e instanceof NumberFormatException }
We can return an integer representing the sign:
assert Integer.signum(45i) == 1
assert Integer.signum(0i) == 0
assert Integer.signum(-43i) == -1
assert Long.signum(-43L) == -1
We can compare fixed-size integers with each other:
assert 45i.compareTo( 47L ) < 0
assert (45 as byte).compareTo( 43 as short ) > 0
assert 45.compareTo( 45 ) == 0
Calculations with Fixed-Size Integers
We can perform addition, subtraction, multiplication, exponents, modulos, and negations on Integers and Longs, using both an operator syntax and a method syntax:
assert 34 + 33 == 67 && 34.plus( 33 ) == 67
assert 34L - 21L == 13L && 34L.minus( 21L ) == 13L
assert 3 * 31 == 93 && 3.multiply( 31 ) == 93
assert 23 % 3 == 2 && 23.mod( 3 ) == 2
assert 3**2 == 9 && 3.power( 2 ) == 9
Not all calculations have a special operator symbol:
assert 22.intdiv(5) == 4
assert (-22).intdiv(5) == -4
assert (-34).abs() == 34
assert (-34L).abs() == 34L
We can increment and decrement variables, using operators, either before and after evaluation:
def a= 7
assert a++ == 7 && a == 8 && a-- == 8 && a == 7 &&
++a == 8 && a == 8 && --a == 7 && a == 7
def b = 7, c = 7 //These operators use methods next() and previous()
assert ( ++b ) == ( c = c.next() )
assert b == c
assert ( --b ) == ( c = c.previous() )
assert b == c
assert ( b++ ) == { def z = c; c = c.next(); z }()
assert b == c
def b= Integer.MAX_VALUE
assert ++b == Integer.MIN_VALUE && --b == Integer.MAX_VALUE
Rules of parentheses and precedence apply to these operators. The operators have the same precedence irrespective of what type of values they operate on.
assert 3*(4+5) != 3*4+5 //parenthesized expressions always have highest precedence
assert -3**2 == -(3**2) //power has next highest precedence
assert ( 2*3**2 == 2*(3**2) ) && ( 2*3**2 != (2*3)**2 )
assert -3+2 != -(3+2) //unary operators have next highest precedence
assert -~234 == -(~234) //unary operators group right-to-left
//multiplication and modulo have next highest precedence
assert 3*4%5 == (3*4)%5 //multiplication and modulo have equal precedence
assert 3%4*5 == (3%4)*5
//addition and subtraction have equal precedence, lower than mult/etc
assert 4+5-6 == 3
assert 5+3*4 == 5+(3*4)
Integers often convert their types during math operations. For + - *, a Long with an Integer converts the Integer to a Long:
assert (23i+45L).class == Long
Because the fixed-sized integers have fixed width, they might overflow their boundaries during math operations, so we need to be aware of the range of values we'll use a fixed-size integer for:
//each 256 is an int, so final product also an int, and calc overflowed...
assert 256*256*256*256 == 0
//we can fix this problem by using a long at the beginning of the calculation...
assert 256L*256*256*256 == 4294967296L
We can compare fixed-size integers using < <= > >= operators, of lower precedence than addition/etc:
assert 14 > 7 && 14.compareTo(7) > 0
assert 14 >= 8 && 14.compareTo(8) >= 0
assert -4 < 3 && (-4).compareTo(3) < 0
assert -14 <= -9 && (-14).compareTo(-9) <= 0
The operators == != <=> are of lower precedence than the other comparison operators:
def a = 4, b = 4, c = 5
assert a == b && a.equals(b)
assert a != c && ! a.equals(c)
assert (4 <=> 7) == -1 && 4.compareTo(7) == -1
assert (4 <=> 4) == 0 && 4.compareTo(4) == 0
assert (4 <=> 2) == 1 && 4.compareTo(2) == 1
Bit-Manipulation on Fixed-Sized Integers
We can examine and manipulate the individual bits on the fixed-sized integers.
To return an int or long with a single 1-bit in the position of the highest-order 1-bit in the argument:
assert Integer.highestOneBit( 45 ) == 32
assert Integer.highestOneBit( 27 ) == 16
assert Integer.highestOneBit( 0 ) == 0
assert Integer.highestOneBit( -1 ) == -128*256*256*256
assert Long.highestOneBit( -1L ) == -128*256*256*256 * 256*256*256*256
assert Integer.lowestOneBit( 45i ) == 1 //match lowest order 1-bit in argument
assert Integer.lowestOneBit( 46i ) == 2
assert Integer.lowestOneBit( 48i ) == 16
To return the number of zero bits preceding the highest-order 1-bit:
[ 0:32, 1:31, 2:30, 4:29 ].each{ k, v->
assert Integer.numberOfLeadingZeros( k ) == v
//returns the number of zero-bits preceding the highest-order 1-bit
assert Long.numberOfLeadingZeros( k as long ) == v + 32
}
[ 0:32, 45:0, 46:1, 48:4 ].each{ k, v->
assert Integer.numberOfTrailingZeros( k ) == v
//returns the number of 0-bits following the lowest-order 1-bit
}
//returns the number of 1-bits in the binary representation...
assert Integer.bitCount( 7 ) == 3
assert Integer.bitCount( -1 ) == 32
We can perform a bitwise complement of the bits in a fixed-size integer using the ~ operator:
def x= 0x33333333i
assert ~x == -x - 1
//how bitwise complement and negation are related under 2's-complement
We can shift the bits of a fixed-size integer to the left or right. This is of lower precedence than addition/etc, but higher than the comparison operators.
//shift 4 bits to the left...
assert 0xB4F<<4 == 0xB4F0 && 0xB4F.leftShift( 4 ) == 0xB4F0
//shift 4 bits to the right, dropping off digits...
assert 0xD23C>>4 == 0xD23 && 0xD23C.rightShift( 4 ) == 0xD23
//sign-extension performed when right-shifting...
assert -0xFFF>>4 == -0x100 && (-0xFFF).rightShift( 4 ) == -0x100
//...unless triple >>> used
assert -0xFFF>>>4 == 0xFFFFF00 && (-0xFFF).rightShiftUnsigned(4) == 0xFFFFF00
[ 0xABC, -0x98765 ].each{
it << 8 == it >> -8
}
We can rotate the bits in an integer or long:
assert Integer.rotateLeft( 0x456789AB, 4 ) == 0x56789AB4
//we use multiples of 4 only to show what's happening easier
assert Integer.rotateLeft( 0x456789AB, 12 ) ==
Integer.rotateRight( 0x456789AB, Integer.SIZE - 12 )
//rotating left and right are inverse operations
assert Integer.rotateLeft( 0x456789AB, 32 ) == 0x456789AB //no change here
assert Long.rotateRight( 0x0123456789ABCDEF, 40 ) == 0x6789ABCDEF012345
We can perform bitwise 'and', 'or', and 'xor' operations on fixed-size integers. This is of lower precedence than the comparison operators.
assert (0x33 & 0x11) == 0x11 && 0x33.and(0x11) == 0x11
assert (0x33 | 0x11) == 0x33 && 0x33.or(0x11) == 0x33
assert (0x33 ^ 0x11) == 0x22 && 0x33.xor(0x11) == 0x22
We can reverse the bits or bytes of the binary representation of an int or long:
assert Integer.toString( 123456, 2 ) == '11110001001000000'
assert Integer.toString( Integer.reverse( 123456 ), 2 ) ==
'10010001111000000000000000' //reverse bits
assert Integer.reverseBytes( 0x157ACE42 ) == 0x42CE7A15 //also works for bytes
Boolean, Conditional, and Assignment Operators with Fixed-Sized Integers
The boolean, conditional, and assignment operators are of even lower precedence than the bitwise operators.
When using an integer with boolean operators !, &&, and ||, 0 evaluates to false, while every other integer evaluates to true:
assert ! 0; assert 1; assert 2; assert -1; assert -2
assert ( ! 1 && 0 ) != ( ! (1 && 0) )
// the unary ! has the same, high, precedence as the other unary operators
assert ( 1 || 0 && 0 ) != ( (1 || 0) && 0 ) // && has higher precedence than ||
The boolean operators && and || only have their operands evaluated until the final result is known. This affects operands with side effects, such as increment or decrement operators:
def x = 0
0 && x++
assert x == 0
//x++ wasn't performed because falsity of (0 && x++) was known when 0 evaluated
1 || x++
assert x == 0
//x++ wasn't performed because truth of (1 || x++) was known when 1 evaluated
We can use the conditional operator ?:, of lower precedence than the boolean operators, to choose between two values:
def x= 1? 7: -5
assert x == 7
We can put the assignment operator = within expressions, but must surround it with parentheses because its precedence is lower than the conditional:
def x, y = (x = 3) && 1
assert (x == 3) && y
def i = 2, j = (i=3) * i
//in the multiplication, lefthand (i=3) evaluated before righthand i
assert j == 9
Of equal precedence as the plain assignment operator = are the quick assignment *= += -= %= **= <<= >>= >>>= &= ^= |= operators:
def a = 7
a += 2 //short for a = a + 2
assert a == 9
a += (a = 3) //expands to a = a + (a = 3) before any part is evaluated
assert a == 12
BigIntegers
The BigInteger has arbitrary precision, growing as large as necessary to accommodate the results of an operation.
We can explicitly convert fixed-sized integers to a BigInteger, and vice versa:
assert 45i as BigInteger == 45g
assert 45L.toBigInteger() == 45g
assert 45g as Integer == 45i
assert 45g.intValue() == 45i //alternate syntax
assert 45g as Long == 45L
assert 45g.longValue() == 45L
assert 256g as Byte == 0
//if converted number too large for target, only lowest order bits returned
assert 200g as byte == -56 //...and this may result in a negative number
A method and some fields that give a little more efficiency:
assert BigInteger.valueOf( 45L ) == 45g
//works for longs only (not for ints, shorts, or bytes)
assert BigInteger.ZERO == 0g
assert BigInteger.ONE == 1g
assert BigInteger.TEN == 10g
We can construct a BigInteger using an array of bytes:
assert new BigInteger( [1,2,3] as byte[] ) == 1g*256*256 + 2*256 + 3
//big-endian 2's complement representation
try{new BigInteger( [] as byte[] ); assert 0}
catch(e){assert e instanceof NumberFormatException} //empty array not allowed
assert new BigInteger( -1, [1,2] as byte[] ) == -258g
//we pass in sign as a separate argument
assert new BigInteger( 1, [1,2] as byte[] ) == 258g
assert new BigInteger( 0, [0,0] as byte[] ) == 0g
assert new BigInteger( 1, [] as byte[] ) == 0 //empty array allowable
try{ new BigInteger( 2, [1,2,3] as byte[] ); assert 0 }
catch(e){ assert e instanceof NumberFormatException}
//sign value must be -1, 0, or 1
We can convert a BigInteger back to an array of bytes:
def ba= (1g*256*256 + 2*256 + 3).toByteArray()
//big-endian 2's complement representation
assert ba.size() == 3 && ba[ 0 ] == 1 && ba[ 1 ] == 2 && ba[ 2 ] == 3
def bb= 255g.toByteArray()
assert bb.size() == 2 && bb[ 0 ] == 0 && bb[ 1 ] == -1
//always includes at least one sign bit
def bc= (-(2g*256 + 3)).toByteArray()
assert bc.size() == 2 && bc[ 0 ] == -3 && bc[ 1 ] == -3
We can pass in a string in a certain base/radix:
assert '27'.toBigInteger() == 27g
assert new BigInteger("27", 10) == 27g
assert new BigInteger("27") == 27g //default radix is 10
assert new BigInteger("110", 2) == 6g
assert new BigInteger("-1F", 16) == -31g
[ { new BigInteger(" 27", 10) }, //no whitespace allowed in string
{ new BigInteger("Z", Character.MAX_RADIX + 1 ) }, //radix out of range
{ new BigInteger("0", Character.MIN_RADIX - 1 ) }, //radix out of range
].each{
try{ it(); assert 0 }catch(e){ assert e instanceof NumberFormatException }
}
We can convert the BigInteger back to a string:
assert 6g.toString(2) == '110'
assert (-31g).toString(16) == '-1f'
assert 27g.toString() == '27' //default radix is 10
assert 27g.toString( Character.MAX_RADIX + 1 ) == '27'
//radix is 10 if radix argument invalid
We can construct a randomly-generated BigInteger:
assert new BigInteger( 20, new Random() ).toString( 2 ).size() == 20
//20 is max bit length, must be >= 0
assert new BigInteger( 20, new Random() ) >= 0
Arithmetic with BigIntegers
We can perform the usual arithmetic operations + - * using either methods or operations:
assert 34g.plus( 33g ) == 34g + 33g
assert 34g.add( 33g ) == 34g + 33g //alternative name for plus
assert 34g.minus( 21g ) == 34g - 21g
assert 34g.subtract( 21g ) == 34g - 21g //alternative name for minus
assert 3g.multiply( 31g ) == 3g * 31g
assert 7g.negate() == -7g //unary operation/method
assert (-7g).negate() == 7g
For + - *, a BigInteger causes any fixed-width integers in the calculation to be converted to a BigInteger:
assert (45L + 123g).class == BigInteger
assert (23 - 123g).class == BigInteger
assert ( 3g * 31 ).class == BigInteger
assert ( 3 * 31g ).class == BigInteger
assert 3g.multiply( 31 ).class == BigInteger
assert 3.multiply( 31g ).class == BigInteger
We can introduce a BigInteger into an expression with Integers or Longs if overflow may occur. But make sure the BigInteger is introduced before an intermediate value that may overflow, for example, the first-used value in a calculation:
assert 256L*256*256*256 * 256*256*256*256 == 0
//the first 256 is a Long, so each intermediate and final product also Long,
//and calc overflowed
assert 256g*256*256*256 * 256*256*256*256 == 18446744073709551616
//no overflow here because BigInteger introduced in first value
We can also increment and decrement BigIntegers:
def a= 7g
assert a++ == 7g && a == 8g && a-- == 8g && a == 7g &&
++a == 8g && a == 8g && --a == 7g && a == 7g
We can find out the quotient and remainder:
assert 7g.divide( 4g ) == 1g
assert 7g.remainder( 4g ) == 3g
def a= 7g.divideAndRemainder( 4g )
assert a[0] == 1g //quotient, same result as divide()
assert a[1] == 3g //remainder, same result as remainder()
assert 7g.divide( -4g ) == -1g
assert 7g.remainder( -4g ) == 3g
assert (-7g).divide( 4g ) == -1g
assert (-7g).remainder( 4g ) == -3g
//division of a negative yields a negative (or zero) remainder
assert (-7g).divide( -4g ) == 1g
assert (-7g).remainder( -4g ) == -3g
Other methods for arithmetic:
assert 22g.intdiv(5g) == 4g
assert (-22g).intdiv(5g) == -4g
assert 7g.abs() == 7g //absolute value
assert (-7g).abs() == 7g
assert 28g.gcd(35g) == 7g
//greatest common divisor of absolute value of each number
assert (-28g).gcd(35g) == 7g
assert 28g.gcd(-35g) == 7g
assert (-28g).gcd(-35g) == 7g
assert 0g.gcd(9g) == 9g
assert 0g.gcd(0g) == 0g
assert 4g**3 == 64g //raising to the power
assert (4g**3).class == Integer
//raising to the power converts a BigInteger to an integer
assert 4g.power(3) == 64g //using method
assert 4g.pow(3) == 64g
//pow() is different to, and sometimes slower than, power()
assert (-4g).power(3) == -64g
assert 4g.power(0) == 1g //exponent must be integer >=0
assert 7g % 4g == 3g && 7g.mod( 4g ) == 3g
//modulo arithmetic, using operator or method
assert 8g % 4g == 0g
assert -7g % 4g == 1g
//result of mod is between 0 and (modulus - 1) inclusive
try{ 7g % -4g; assert 0 }catch(e){ assert e instanceof ArithmeticException }
//mod value must be positive
assert 4g.modPow( 3g, 9g ) == 1
//calculates as ((4**3) mod 9), result always zero or positive
assert 4g.modPow( -2g, 9g ) == 4
//negative exponents allowed, but mod value must be positive
assert 4g.modInverse( 3g ) == 1 //calculates as ((4**-1) mod 3)
//mod must be positive, and value must have a multiplicative inverse mod m
//(ie, be relatively prime to m)
assert 7g.max(5g) == 7g //maximum and minimum
assert 4g.min(5g) == 4g
def a=5g, b=5g, c=a.min(b)
assert [a,b].any{ c.is(it) }
//either a or b may be returned if they're both equal
assert (-45g <=> -43g) && ( (-45g).compareTo( -43g ) == -1 )
//comparing two BigIntegers
assert 14g >= 8g && 14g.compareTo(8g) >= 0
assert 45g.signum() == 1 //return sign as -1,0, or 1
assert 0g.signum() == 0
assert (-43g).signum() == -1
We can construct a randomly generated positive BigInteger with a specified bit length (at least 2 bits), that is probably prime to a specific certainty. The probability the BigInteger is prime is >(1 - (1/2)**certainty). If the certainty <=0, true always returned. The execution time is proportional to the value of this parameter. We must pass in a new Random object:
100.times{
def primes= [17g, 19g, 23g, 29g, 31g]
//bitlength is 5, so primes from 16 to 31 incl
assert new BigInteger( 5, 50, new Random() ) in primes
//5 is bit-length, 50 is certainty (must be integer)
}
def pp= BigInteger.probablePrime( 20, new Random() )
//if we don't want to specify certainty
//20 is bit-length; there's <1.0e-30 chance the number isn't prime
def pn= pp.nextProbablePrime()
//this is probably next prime, but definitely no primes skipped over
( (pp+1)..<pn ).each{
assert ! it.isProbablePrime(50)
//we can test for primality to specific certainty (here, 50).
//True if probably prime, false if definitely composite
}
assert 10g.nextProbablePrime() == 11
assert 0g.nextProbablePrime() == 2
Bit-Manipulation on BigIntegers
All operations behave as if BigIntegers were represented in two's-complement notation.
Bit operations operate on a single bit of the two's-complement representation of their operand/s. The infinite word size ensures that there are infinitely many virtual sign bits preceding each BigInteger. None of the single-bit operations can produce a BigInteger with a different sign from the BigInteger being operated on, as they affect only a single bit.
Bit operations operate on a single bit of the two's-complement representation of their operand/s. The infinite word size ensures that there are infinitely many virtual sign bits preceding each BigInteger. None of the single-bit operations can produce a BigInteger with a different sign from the BigInteger being operated on, as they affect only a single bit.
assert 0x33g.testBit(1)
//true if bit is 1, indexing beginning at 0 from righthand side
assert ! 0x33g.testBit(2)
(2..100).each{
assert (-0x3g).testBit(it)
//negative BigIntegers have virtual infinite sign-extension
}
Unlike with fixed-width integers, BigIntegers don't have a method to show the hex, octal, or binary representation of a negative number. We can use this code instead to look at the first 16 lowest-order virtual bits:
def binRepr={n->
(15..0).inject(''){flo,it->
flo<< (n.testBit(it)? 1: 0)
}
}
assert 0x33g.toString(2) == '110011'
assert binRepr(0x33g) as String == '0000000000110011'
assert (-0x33g).toString(2) == '-110011' //not what we want to see
assert binRepr(-0x33g) as String == '1111111111001101'
//notice the negative sign bit extended virtually
More bit-manip methods:
assert 0x33g.setBit(6) == 0x73g //0x33g is binary 110011
assert 0x33g.clearBit(4) == 0x23g
assert 0x33g.flipBit(1) == 0x31g
assert 0x33g.flipBit(2) == 0x37g
assert 0x1g.getLowestSetBit() == 0
//index of the rightmost one bit in this BigInteger
assert 0x2g.getLowestSetBit() == 1
assert 0x8g.getLowestSetBit() == 3
assert 0x33g.bitLength() == 6
//number of bits in minimal representation of number
assert (-0x33g).bitLength() == 6 //exclude sign bit
assert 0x33g.bitCount() == 4 //number of bits that differ from sign bit
assert (-0x33g).bitCount() == 3
Setting, clearing, or flipping bit in virtual sign makes that bit part of the number:
assert (-0x33g).clearBit(9) == -0x233g
We can perform bit-shifting on BigIntegers. The shortcut operators >> and << can't be used, only the method names can be (they're also spelt differently to the fixed-size integer versions of the names, eg, "shiftLeft" instead of "leftShift"). There's no shift-right-unsigned method because this doesn't make sense for BigIntegers with virtual infinite-length sign bits.
assert 0xB4Fg.shiftLeft( 4 ) == 0xB4F0g //shift 4 bits to the left
assert 0xD23Cg.shiftRight( 4 ) == 0xD23g
//shift 4 bits to the right, dropping off digits
assert (-0xFFFg).shiftRight( 4 ) == -0x100g
//sign-extension performed when right-shifting
[ 0xABCg, -0x98765g ].each{
it.shiftLeft( 8 ) == it.shiftRight( -8 )
}
We can perform 'not', 'and', 'or', and 'xor' bitwise operations on BigIntegers:
assert 123g.not() == -124g //in 2's-complement, negate and add 1
assert -0xFFg.not() == 0x100g
assert ( (0x33g & 0x11g) == 0x11g) && 0x33g.and(0x11g) == 0x11g
assert ( (0x33g | 0x11g) == 0x33g) && 0x33g.or(0x11g) == 0x33g
assert ( (0x33g ^ 0x11g) == 0x22g) && 0x33g.xor(0x11g) == 0x22g
assert 0x33g.andNot(0x11g) == 0x22g && (0x33g & (~ 0x11g)) == 0x22g
//convenience operation
For negative numbers:
// 兩個都是負數 and returns a negative if both operands are negative... assert (-1g & -1g) == -1g // 兩個或有負數 or returns a negative number if either operand is negative... assert (1g | -1g) == -1g
// 兩個反或負數 xor returns a negative number if exactly one operand is negative... assert (1g ^ -1g) == -2g assert (-1g ^ -2g) == 1g
When the two operands are of different lengths, the sign on the shorter of the two operands is virtually extended prior to the operation:
assert 11g.and(-2g) == 10g //01011 and 11110 is 01010, ie, 10g
訂閱:
文章 (Atom)