SerraAvenger
Cuz I can
- Reaction score
- 234
What it is
This is my approach to get over the 2^31-1 integer size.
It uses a struct called longinteger that contains a couple of integers - basically it is a base1.000.000.000 integer with SIZE digits.
USES vJASS
How to implement it
If you haven't got JassPack NewGen, get it.
Create a new trigger, name it appropriately, and convert it to custom text.
Copy and paste the code into your newly created trigger. Overwrite anything currently in it.
How to use it
If you are working inside of a library ( the vJASS thing. Not the one with the books ), you will first have to make sure the library knows where to find the functions from this library.
The line in which you create the library needs to look like this:
If you're not working in a library, then it doesn't matter.
An example says more than thousand words, so here is one:
What does work:
- Positive longintegers ( negative is on the way )
- Addition
What won't work ( as in never ):
- Multiplication / division
What will come:
- Negative longintegers
- Comparision
The Code
This is my approach to get over the 2^31-1 integer size.
It uses a struct called longinteger that contains a couple of integers - basically it is a base1.000.000.000 integer with SIZE digits.
USES vJASS
How to implement it
If you haven't got JassPack NewGen, get it.
Create a new trigger, name it appropriately, and convert it to custom text.
Copy and paste the code into your newly created trigger. Overwrite anything currently in it.
How to use it
If you are working inside of a library ( the vJASS thing. Not the one with the books ), you will first have to make sure the library knows where to find the functions from this library.
The line in which you create the library needs to look like this:
Code:
library NAME [I]initialiser FUNC_NAME[/I] requires [I]OTHER_STUFF, [/I] LongInt
An example says more than thousand words, so here is one:
JASS:
library TestingLongInt initializer Init requires LongInt
function Init takes nothing returns nothing
local longinteger long1 // the type name is longinteger
local longinteger long2
set long1 = CreateLong( 0 ) // CreateLong( integer ) creates a new longinteger. The integer argument assings the starting value.
set long2 = S2L ( "123456789123456789" ) // S2L( string ) is another way to create a longinteger. It basically converts the string argument to the longinteger
call LongAddInt( long1, 5000 ) // Adds an integer to long1.
call LongAddLongEx( long1, long2, false ) // LongAddLongEx adds long2 to long1. The parameter specifies whether long2 shall be destroyed during the process or not.
call LongAddLong( long1, long2 ) // same as above, just that long2 will always be destroyed.
call BJDebugMsg( L2S( long1 ) ) // L2S converts a long to a string. It is the inverse function of S2L.
call DestroyLong( long1 ) // Destroys long1. If you don't destroy longs once you no longer need them, you might get a memory leak. "nulling" is not required, as a longinteger is no handle.
endfunction
endlibrary
What does work:
- Positive longintegers ( negative is on the way )
- Addition
What won't work ( as in never ):
- Multiplication / division
What will come:
- Negative longintegers
- Comparision
The Code
JASS:
library LongInt
// Version 0.5
globals
constant integer SIZE = 4 // max numbersize = MAX_PART_SIZE ^ SIZE = 10^(9*SIZE)
endglobals
struct longinteger
private integer array part[ SIZE ]
private integer parts = 1
static constant integer MAX_PART_SIZE = 1000000000 // The base of the number ( 1.000.000.000 )- DON'T CHANGE!
static constant integer LOG_PART_SIZE = 9 // log( MAX_PART_SIZE ) - DON'T CHANGE!
static method create takes integer base returns longinteger
local longinteger new = .allocate()
local integer i = 0
loop
exitwhen i >= SIZE
set new.part[ i ] = 0
set i = i + 1
endloop
set new.part[0] = base
call new.partition()
return new
endmethod
static method from_s takes string s returns longinteger
local longinteger new = .allocate()
local integer sLen = StringLength( s )
local integer parts = sLen / .LOG_PART_SIZE
local integer i = 0
local integer dI = .LOG_PART_SIZE
if SIZE < parts then
debug call BJDebugMsg( SCOPE_PREFIX + ": Size is smaller than required ( " + I2S( SIZE ) + " / " + I2S( parts ) + " )!" )
set parts = SIZE
set s = SubString( s, sLen - ( parts * .LOG_PART_SIZE ), sLen )
set sLen = parts * .LOG_PART_SIZE
endif
set new.parts = parts
loop
exitwhen i >= parts
set new.part[ i ] = S2I( SubString( s, sLen - (i+1) * dI, sLen - i*dI ) )
set i = i + 1
endloop
return new
endmethod
private method partitionIndex takes integer index returns nothing
if IAbsBJ( .part[ index ] ) >= .MAX_PART_SIZE then
set .part[ index + 1 ] = .part[ index + 1 ] + .part[ index ] / .MAX_PART_SIZE
set .part[ index ] = .part[ index ] - ( .part[ index ] / .MAX_PART_SIZE ) * .MAX_PART_SIZE
if .parts <= index then
set .parts = index + 1
endif
endif
endmethod
private method partition takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= .parts
call .partitionIndex( i )
set i = i + 1
endloop
endmethod
method addLong takes longinteger other, boolean destroyOther returns longinteger
local integer partsTotal = IMaxBJ( .parts, other.parts )
local integer i = 0
loop
exitwhen i >= partsTotal
set .part[ i ] = .part[ i ] + other.part[ i ]
call .partitionIndex( i )
set i = i + 1
endloop
set .parts = partsTotal
if destroyOther then
call other.destroy()
endif
return this
endmethod
method addInt takes integer other returns longinteger
return .addLong( .create( other ), true )
endmethod
method to_s takes nothing returns string
local integer i = .parts - 1
local string res = ""
loop
exitwhen i < 0
set res = res + I2S( .part[ i ] )
set i = i - 1
endloop
return res
endmethod
endstruct
function CreateLong takes integer base returns longinteger
return longinteger.create( base )
endfunction
function LongAddLongEx takes longinteger l1, longinteger l2, boolean destroyOther returns longinteger
return l1.addLong( l2, destroyOther )
endfunction
function LongAddLong takes longinteger l1, longinteger l2 returns longinteger
return l1.addLong( l2, true )
endfunction
function LongAddInt takes longinteger l, integer int returns longinteger
return l.addInt( int )
endfunction
function L2S takes longinteger l returns string
return l.to_s()
endfunction
function S2L takes string s returns longinteger
return longinteger.from_s( s )
endfunction
function DestroyLong takes longinteger toDestroy returns nothing
call toDestroy.destroy()
endfunction
endlibrary