Problem adding Ulongint numbers

New to FreeBASIC? Post your questions here.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

Seems this works:

Image

Code: Select all

Function POT(ByVal num As Integer)As ULongInt
	Dim i As Integer
	Dim resultado As ULongInt
	resultado=1
	For i=1 To num
		resultado=resultado*2
	Next
	POT=resultado
End Function
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Problem adding Ulongint numbers

Post by MrSwiss »

I don't really understand what exactly you're after.
If it's the maximum value a ULongInt can hold use:

Code: Select all

Const As ULongInt ULImax = &hFFFFFFFFFFFFFFFF
Just print it out to get the DEC equivalent.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

MrSwiss wrote:I don't really understand what exactly you're after.
If it's the maximum value a ULongInt can hold use:

Code: Select all

Const As ULongInt ULImax = &hFFFFFFFFFFFFFFFF
Just print it out to get the DEC equivalent.
Sorry, not understand :-(

I need to calculate the addition of several 2^x numbers.

A 64 bits word is used as a chessboard. For example all the possible moves for a bishop in some place of the board, is represented by a 1 in each possible place the bishop could reach and 0 in all other places.
I need to calculate the number of this 64 bits word with 1s in those places.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

So I need to calculate 2^x1+2*x2+...+2^xn (where xi are any numbers from 0 to 63) exactly, because if not, that means the bishop could move where it couldnt. Or do not move where it could.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

I need to caclulate it for a bishop in each of the 64 squares of the board and in the 4 directions it could move.
The same for the rook.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Problem adding Ulongint numbers

Post by caseih »

Yeah I'm confused too. Why are you doing exponentiation when you're really just after a bit mask. Just use bit shifting. That's what it's there for and CPUs can do it super efficiently with no math. To be clear, say you want to turn on bits x,y, and z. Instead of multiplying out 2 to the powers of x, y, and z, just do some bitwise operations:

Code: Select all

a = (1 shl x) OR (1 shl y) OR (1 shl z)
Hopefully you get the picture. This is a classic bit mask.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

caseih wrote:Yeah I'm confused too. Why are you doing exponentiation when you're really just after a bit mask. Just use bit shifting. That's what it's there for and CPUs can do it super efficiently with no math. To be clear, say you want to turn on bits x,y, and z. Instead of multiplying out 2 to the powers of x, y, and z, just do some bitwise operations:

Code: Select all

a = (1 shl x) OR (1 shl y) OR (1 shl z)
Hopefully you get the picture. This is a classic bit mask.
Mmmm..... I´m not sure if I could do it this way. The other way was the first I thought. Well, the second, the first was complete it manually (with the help of this: http://www.talkchess.com/forum3/viewtopic.php?t=39053 ) as i did with knights moves (but for bishpos and rooks are too many to do it manually so I thought what I said)! :-D

Code: Select all

'Ataques caballos:
For i=0 To 63
	Read AtaquesCaballos(i)
Next
Data 132096,329728,659712,1319424,2638848,5277696,10489856,4202496
Data 33816580,84410376,168886289,337772578,675545156,1351090312,2685403152,1075839008
Data 8657044482,21609056261,43234889994,86469779988,172939559976,345879119952,687463207072,275414786112
Data 2216203387392,5531918402816,11068131838464,22136263676928,44272527353856,88545054707712,175990581010432,70506185244672
Data 567348067172352,1416171111120896,2833441750646784,5666883501293568,11333767002587136,22667534005174272,45053588738670592,18049583422636032
Data 145241105196122112,362539804446949376,725361088165576704,1450722176331153408,2901444352662306816,5802888705324613632,11533718717099671552,4620693356194824192
Data 288234782788157440,576469569871282176,1224997833292120064,2449995666584240128,4899991333168480256,9799982666336960512,1152939783987658752,2305878468463689728
Data 1128098930098176,2257297371824128,4796069720358912,9592139440717824,19184278881435648,38368557762871296,4679521487814656,9077567998918656

'Ataques Alfiles:
'Noreste:
For f=1 To 8
	For c=1 To 8
		fa=f
		ca=c
		While (fa<8 And ca<8)
			fa=fa+1
			ca=ca+1
			pivote=DosALa(8*(fa-1)+(ca-1))
			AtaquesAlfilesNE(8*(f-1)+(c-1))=AtaquesAlfilesNE(8*(f-1)+(c-1))+pivote
		Wend
		'Print 8*(f-1)+(c-1),AtaquesAlfilesNE(8*(f-1)+(c-1))
		'Sleep 
	Next
Next
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

As I said, do not matter the time it takes cause it is needed just before start the game. But may be is nicer the way you said. I need to understand it better.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Problem adding Ulongint numbers

Post by dodicat »

You could use a string adder.

Code: Select all



Dim Shared As Ubyte addmod(0 To 19),addbool(0 To 19) 'lookup array
For z As Integer=0 To 19
    addmod(z)=(z Mod 10+48)
    ADDbool(z)=(-(10<=z))
Next z 

Function plus(_num1 As String,_num2 As String) As String
    Var _flag=0,n_=0
    Dim As Ubyte addup=Any,addcarry=Any
    #macro finish()
    answer=Ltrim(answer,"0")
    If _flag=1 Then Swap _num2,_num1
    Return answer
    #endmacro
    If Len(_num2)>Len(_num1) Then 
        Swap _num2,_num1
        _flag=1
    End If
    Var diff=Len(_num1)-Len(_num2)
    Var answer="0"+_num1
    addcarry=0
    For n_=Len(_num1)-1 To diff Step -1 
        addup=_num2[n_-diff]+_num1[n_]-96
        answer[n_+1]=addmod(addup+addcarry)
        addcarry=addbool(addup+addcarry)
    Next n_ 
    If addcarry=0 Then 
        finish()
    End If
    If n_=-1 Then 
        answer[0]=addcarry+48
        finish()
        Endif
        For n_=n_ To 0 Step -1 
            addup=_num1[n_]-48
            answer[n_+1]=addmod(addup+addcarry)
            addcarry=ADDbool(addup+addcarry)
            If addcarry=0 Then Exit For
        Next n_
        answer[0]=addcarry+48
        finish()
    End Function
    
    Function bigger(num2 As String,num1 As String) As Long
        Var lens=Len(num2),lenf=Len(num1)
        If Lens>lenf Then Return -1
        If Lens<lenf Then Return 0
        If NUM2>NUM1 Then Return -1 Else Return 0
    End Function
    
    
    Dim As Ulongint temp
    Dim As String s(63)
    For i As Long=0 To 63
        Read temp
        s(i)=Str(temp)
    Next
    
    Data 132096,329728,659712,1319424,2638848,5277696,10489856,4202496
    Data 33816580,84410376,168886289,337772578,675545156,1351090312,2685403152,1075839008
    Data 8657044482,21609056261,43234889994,86469779988,172939559976,345879119952,687463207072,275414786112
    Data 2216203387392,5531918402816,11068131838464,22136263676928,44272527353856,88545054707712,175990581010432,70506185244672
    Data 567348067172352,1416171111120896,2833441750646784,5666883501293568,11333767002587136,22667534005174272,45053588738670592,18049583422636032
    Data 145241105196122112,362539804446949376,725361088165576704,1450722176331153408,2901444352662306816,5802888705324613632,11533718717099671552,4620693356194824192
    Data 288234782788157440,576469569871282176,1224997833292120064,2449995666584240128,4899991333168480256,9799982666336960512,1152939783987658752,2305878468463689728
    Data 1128098930098176,2257297371824128,4796069720358912,9592139440717824,19184278881435648,38368557762871296,4679521487814656,9077567998918656
    For n As Long=0 To 63
        Print "s(";n;") = "; s(n)
    Next
    Print
    
    
    Dim As String max="18446744073709551615"
    Dim As String tot="0"
    dim as double check
    print "Sum up all the array elements"
    print "Sums string";tab(50);"Sums Doubles"
    For n As Long=0 To 63
        tot=plus(s(n),tot)
        check+=val(s(n))
        Print tot+Iif(bigger(tot,max),"  outside ulongint","");tab(50);check
    Next
    Print
    Print "check all added pairs outside ulongint:"
    For n1 As Long=Lbound(s) To Ubound(s)-1
        For n2 As Long=n1+1 To Ubound(s)
            If bigger(plus(s(n1),s(n2)),max) Then
                Print " ";s(n1);"  =s(";n1;")"
                Print "+";s(n2);"  =s(";n2;")"
                Print "_________________"
                Print plus(s(n1),s(n2)),"  outside ulongint"
            End If
        Next
    Next
    'dim as ulongint z=-1
    Sleep
    
    
    
     
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

Wow! Thanks for your time dodicat!

I need time to understand it.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

caseih wrote:Yeah I'm confused too. Why are you doing exponentiation when you're really just after a bit mask. Just use bit shifting. That's what it's there for and CPUs can do it super efficiently with no math. To be clear, say you want to turn on bits x,y, and z. Instead of multiplying out 2 to the powers of x, y, and z, just do some bitwise operations:

Code: Select all

a = (1 shl x) OR (1 shl y) OR (1 shl z)
Hopefully you get the picture. This is a classic bit mask.
Not sure if I understand what you said, but your comment made me find a far simpler solution:

Code: Select all

'Ataques Alfiles:
'Noreste:
For f=1 To 8
	For c=1 To 8
		fa=f
		ca=c
		While (fa<8 And ca<8)
			fa=fa+1
			ca=ca+1
			AtaquesAlfilesNE(8*(f-1)+(c-1))=AtaquesAlfilesNE(8*(f-1)+(c-1)) Or BitSet(AtaquesAlfilesNE(8*(f-1)+(c-1)),(8*(fa-1)+(ca-1))) 
		Wend
		'Print 8*(f-1)+(c-1),AtaquesAlfilesNE(8*(f-1)+(c-1))
		'Sleep 
	Next
Next
Instead of use expotentiation, just set the bit I want.
It est: instead of ULB=ULB+2^x, do ULB=ULB OR bitset(ULB,x)
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Problem adding Ulongint numbers

Post by badidea »

Don't use ^ with integers. The ^ operator takes 2 doubles as inputs and returns a double. When used with integers, automatic conversion to and from doubles is done. Example:

Code: Select all

Dim a As ULongInt
a=18049651735527936
Print a+2^0
Sleep
Prints: 1.804965173552794e+16

Interestingly fbc 32-bit behaves different fbc 64-bit. For this code:

Code: Select all

Dim a As ULongInt
a = 18049651735527936
a = a + 2 ^ 0 'conversion from and to ULongInt happens here
Print a
Sleep
linux fbc 32-bit --> 18049651735527937
linux fbc 64-bit --> 18049651735527936

OK with with this code:

Code: Select all

Dim a As ULongInt
a = 18049651735527936
a = a + cast(ULongInt, 2 ^ 0)
Print a
Sleep
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Problem adding Ulongint numbers

Post by MrSwiss »

A 64 bits word is used as a chessboard.
Fine, but not enough information about the layout.
If I assume for instance: field (on chess board) A1 is represented in bit 0 (lowermost bit) then:
is bit 1 representative for A2, or B1? e.t.c. while you might know those things, others here don't ...
Is my first assumption correct or not?
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

MrSwiss wrote:
A 64 bits word is used as a chessboard.
Fine, but not enough information about the layout.
If I assume for instance: field (on chess board) A1 is represented in bit 0 (lowermost bit) then:
is bit 1 representative for A2, or B1? e.t.c. while you might know those things, others here don't ...
Is my first assumption correct or not?
bit 0 is A1
bit 1 is B1
bit 8 is A2
bit 63 is H8
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Problem adding Ulongint numbers

Post by Luis Babboni »

badidea wrote:Don't use ^ with integers. The ^ operator takes 2 doubles as inputs and returns a double. When used with integers, automatic conversion to and from doubles is done. Example:

Code: Select all

Dim a As ULongInt
a=18049651735527936
Print a+2^0
Sleep
Prints: 1.804965173552794e+16

Interestingly fbc 32-bit behaves different fbc 64-bit. For this code:

Code: Select all

Dim a As ULongInt
a = 18049651735527936
a = a + 2 ^ 0 'conversion from and to ULongInt happens here
Print a
Sleep
linux fbc 32-bit --> 18049651735527937
linux fbc 64-bit --> 18049651735527936

OK with with this code:

Code: Select all

Dim a As ULongInt
a = 18049651735527936
a = a + cast(ULongInt, 2 ^ 0)
Print a
Sleep
Thanks badidea.
I solved the problem doing this:

Instead of use expotentiation, just set the bit I want.
It est: instead of ULB=ULB+2^x, do ULB=ULB OR bitset(ULB,x)
Post Reply