Bin2Dec() »»» Converting binary numbers to decimal system

Share your advanced PureBasic knowledge/code with the community.
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Bin2Dec() »»» Converting binary numbers to decimal system

Post by AND51 »

Hello!

This is just another nice competition. But I also request the procedures from this threads to be included into the next version of PB.
  • This a nice Bin2Dec() functin, converting even high numbers (returning value is a quad). This makes it possible to convert any BinQ()-values back to the decimal system. Even negative binary numbers are supported! Furthemore, you can use this procedure with Unicode.
My function can be reduced by 1 line, but unfortunately there is a bug regarding quads. Fred must fix this: http://www.purebasic.fr/english/viewtopic.php?t=25367

Code: Select all

Procedure.q Bin2Dec(binary.s)
	Protected result.q, n, temp
	For n=MemoryStringLength(@binary)-1 To 0 Step -1
		temp=(PeekC(@binary+n*SizeOf(Character))-48)*1<<(MemoryStringLength(@binary)-1-n)
		result+temp ; leave this line untouched, quad-bug otherwise!
	Next
	ProcedureReturn result
EndProcedure


Debug Bin(125)
Debug Bin2Dec(Bin(125))

@ Flype: You're welcome... :lol:
@ Anyone else: You, too! :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

Now beat that:

Code: Select all

Procedure myBin2Dec(s.s, pos.l = 0, temp.l = 0, temp2.l = 0)
  ProcedureReturn (Len(s) And (1+PokeL(@temp2, (PeekC(@s+(Len(s)-1)*SizeOf(Character))-48)*(1<<pos)))) * temp2 + (Len(s) And (1+PokeL(@temp, myBin2Dec(Left(s, Len(s)-1), pos+1)))) * temp
EndProcedure
:D
ok, no quads, but I don't care about bugs. It should work with quads. :wink:
Athlon64 3700+, 1024MB Ram, Radeon X1600
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

@remi_meier
recursive, nice work :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Beeindruckend! :shock:

Very nice, but aren't you "cheating", when you define your variables as procedure-parameters?
I've never seen a PB procedure, doing so.

@ quads: In my opionion, quads are very important, so you shouldn't leave them out. If you're doing so, BinQ() does not make sense any longer...
PB 4.30

Code: Select all

onErrorGoto(?Fred)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

That's no cheating :P
But yes, don't use this procedure in any projects, it has no advantage
at all :wink:

Yes, quads are nice. I don't use them very often. And my code above
just crashes with quads -> I don't care...
Athlon64 3700+, 1024MB Ram, Radeon X1600
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Now I understand you. However, your procedure remains impressively!
Now you can try to beat my "Hex2Dec()" :wink:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

No :wink:
I'll use my time for something else now.
Athlon64 3700+, 1024MB Ram, Radeon X1600
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Much faster, but doesn't take negative numbers:

Code: Select all

Procedure.q Bin2Dec2(Hex.s)
  Protected Result.q
  Protected Char.l
  Ptr = @Hex
  Char = PeekC(Ptr) - '0'
  While Char <> - '0'
    Ptr + SizeOf(Character)
    Result = Result << 1 + Char
    Char = PeekC(Ptr) - '0'
  Wend
  ProcedureReturn Result
EndProcedure
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Nice, but you don't care about clean code, do you?
You don't protect 'ptr' and pay attention to 'EnableExplicit'.

Please, correct this, ok?

Code: Select all

Procedure.q Bin2Dec2(Hex.s) 
  Protected Result.q,Ptr = @Hex, Char.l=PeekC(Ptr) - '0'
  While Char <> - '0' 
    Ptr + SizeOf(Character) 
    Result = Result << 1 + Char 
    Char = PeekC(Ptr) - '0' 
  Wend 
  ProcedureReturn Result 
EndProcedure 


Debug Bin2Dec2("101")
Your performance is good!
PB 4.30

Code: Select all

onErrorGoto(?Fred)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

Actually, that's no clean code either:

Code: Select all

Protected Result.q,Ptr = @Hex, Char.l=PeekC(Ptr) - '0'
Readability does also count :!:
And your pointer isn't a pointer ;)
The Char isn't a char, etc :D
Athlon64 3700+, 1024MB Ram, Radeon X1600
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

OK, ther are too many spaces... I would code like that:

Code: Select all

Protected Result.q, Ptr=@Hex, Char.l=PeekC(Ptr)-'0'
This is clear enough for me. I already got used to this useful feature.

Since PB 4.00, you can directly write into variables while declaring them.

if you get used to this, maybe you'll agree to me.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

I am already used to it, but not for expressions like "PeekC(Ptr)-'0'". I
use it only with literal values like 1, 2, 666 or "Test". And mostly I even
split them in several lines.
You can't tell me that

Code: Select all

Protected Result.q, Ptr=@Hex, Char.l=PeekC(Ptr)-'0'
is more readable than

Code: Select all

Protected Result.q, *Ptr, Char.c

*Ptr = @Hex
Char = PeekC(*Ptr) - '0'
And you really should use the appropriate datatypes for each variable.
Athlon64 3700+, 1024MB Ram, Radeon X1600
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

I use only one declared variable per line, unless i have two related variables that does not need to be initialized and are of the same type.
* is for pointer to structures. I see no reason to use it on a long since the behaviour doesn't change. Also, *Ptr becomes a pointer to a pointer, which isn't right.

This is the cleanest code:

Code: Select all

Procedure.q Bin2Dec2(Hex.s) 
  Protected Result.q 
  Protected Char.l 
  Protected Ptr = @Hex 
  Char = PeekC(Ptr) - '0' 
  While Char <> - '0' 
    Ptr + SizeOf(Character) 
    Result = Result << 1 + Char 
    Char = PeekC(Ptr) - '0' 
  Wend 
  ProcedureReturn Result 
EndProcedure
That's really a mess:

Code: Select all

Protected Result.q,Ptr = @Hex, Char.l=PeekC(Ptr) - '0'
Multiple initializations on one line, no space after comma, no space around = operator and multiple types on one line.
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

No, Trond :)
Ptr and *Ptr are not the same! They are the same, when you don't use
Define.f or something like that. *Ptr is just safer (Ptr.l would just be wrong).
*Ptr is not a pointer to a pointer, that's just possible through structures.

I accept your code, but mine is cleaner :P

Code: Select all

Procedure.l Bin2Dec(s.s)
  Protected *ptr.CHARACTER
  Protected pos.l, Value.l
  
  If s
    pos  = Len(s) - 1
    *ptr = @s
    
    While *ptr\c <> 0
      If *ptr\c = '1'
        Value + (1 << pos)
        
      ElseIf *ptr\c <> '0'
        Value = 0
        Break
        
      EndIf
      
      pos  - 1
      *ptr + SizeOf(CHARACTER)
    Wend
    
  EndIf
  
  ProcedureReturn Value
EndProcedure


Debug Bin2Dec(Bin(125))
(that's how I would write it in a project)
Athlon64 3700+, 1024MB Ram, Radeon X1600
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

clean is a matter of taste, i hate 'break' statements...

anyway, i just reenter the competition with the same code for hextodec :-)

http://www.purebasic.fr/english/viewtopic.php?t=25445

can we now do octals as well? :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply