## Complement a Number

Started by Baggey, October 07, 2023, 18:10:04

#### Baggey

As far as im aware there is no function to complement the Bits of a Number

Ive been Implementing Some Routines that i need to Complement certain bits or a number of bits.

It could be added to by Left to right and even a certain Bit. But I have no need for this right now!

So I put this together Complementing from Right to Left.

Runnable BlitzMaxNG code

`' Takes a Number And Complements each Bit' The Not Command only does the first Bit' Sometimes you need to complement all bits or a certain number' So I wrote this may come in handy for someone' Written by BaggeySuperStrictGlobal DD00:Int=255'DD00:&3 ' And DD00 with 3 ie, 00000011 Retrieve first 2 BitsDD00=255Print RSet(Bin(DD00),8)Print RSet(Bin(Com(DD00,4)),8)Function Com:Int(Num:Int, NumOfBits:Int)     ' Starts NumOFBits from Right to Left     If NumOfBits = Null Return Num     Local Bit:Int=1     Repeat        If (Num & Bit) = 0 Then Num = (Num | Bit) Else Num = (Num &~ Bit)                Bit = Bit Shl 1        NumOfBits:-1             Until (NumOfBits=0)     Return NumEnd Function`
As always if you find this useful use it as you will if not Simply ignore it.

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

#### Midimaster

I guess this can be done with less code:

`Function Com:Int(Num:Int, NumOfBits:Int)    Local Bit:Int = 2^NumOfBits-1    Return num ~ bitEnd Function`
...back from Egypt

#### Baggey

I didnt think of that

I know you can do 2^0, 2^1 etc.. for individual bits. Too get your relevant bit, but doing the lot in one go and then Xoring for the return Neat!

Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

#### Derron

#3
`SuperStrictFramework Brl.StandardIOFunction Com:Int(Num:Int, NumOfBits:Int)    Local Bit:Int = 2^NumOfBits-1    Return num ~ bitEnd Function'in NG we can "inline" it to avoid function call costs if compiler does not do for us'(I assume GCC already inlines both variants here already)Function Com2:Int(Num:Int, NumOfBits:Int) Inline    Return num ~ (1 shl NumOfBits - 1)End Functionprint 1 shl 0print 1 shl 1print 1 shl 2print 1 shl 3print Com(10, 5) + ", " + Com(5002015, 1)print Com2(10, 5) + ", " + Com2(5002015, 1)`

`local runs:int = 100000000local result:int, t:Intresult = 0t = Millisecs()For local i:int = 0 until runs result :+ Com(i, 3)Nextprint "result " + result + " in " + (Millisecs()-t)+"ms."result = 0t = Millisecs()For local i:int = 0 until runs result :+ Com2(i, 3)Nextprint "result " + result + " in " + (Millisecs()-t)+"ms."`
release:
result 887459712 in 238ms.
result 887459712 in 14ms.

debug:
result 887459712 in 8187ms.
result 887459712 in 7115ms.

PS:
`result = 0t = Millisecs()For local i:int = 0 until runs result = result + i ~ (1 shl 3 - 1)Next`
is again 200% faster ... why? because NG already replaces the "1 shl 3 - 1" with "7" during generation of the C code (static expression) and thus of course replacing most of the calculation already. So if you try to compare this, then be aware of "why" it is so much faster.

bye
Ron

#### Baggey

Wow, @Derron

Thankyou for that. You've given me an idea for speed testing my functions Thankyou

com() seems to be the smallest and neatest code however running your speed test gives me a good idea, of which way to go with the coding.

I Put your code together and consolidated my code and ran them to see the Speed Benefits!

I think im going to start working through my Functions to see if i can change and re-write for Speed.

As you probably understand writting an Emulator must have the fastest code execution because of the shear overhead of the instructions.

all methods get/give the same result but speed for me is always of upmost importance

Here is a Runnable Speed test example of all way's in BlitzmaxNG

`' Complement Speed TesterSuperStrictFramework Brl.StandardIOFunction Com:Int(Num:Int, NumOfBits:Int)    Local Bit:Int = 2^NumOfBits-1    Return num ~ bitEnd Function'in NG we can "inline" it to avoid function call costs if compiler does not do for us'(I assume GCC already inlines both variants here already)Function Com2:Int(Num:Int, NumOfBits:Int) Inline    Return num ~ (1 Shl NumOfBits - 1)End FunctionFunction Com3:Int(Num:Int, NumOfBits:Int)     ' Starts NumOFBits from Right to Left     If NumOfBits = Null Return Num     Local Bit:Int=1     Repeat        If (Num & Bit) = 0 Then Num = (Num | Bit) Else Num = (Num &~ Bit)               Bit = Bit Shl 1        NumOfBits:-1            Until (NumOfBits=0)     Return NumEnd FunctionLocal runs:Int = 100000000Local result:Int, t:IntPrintresult = 0t = MilliSecs()For Local i:Int = 0 Until runs result :+ Com(i, 3)NextPrint "result " + result + " in " + (MilliSecs()-t)+"ms.   Midimasters"result = 0t = MilliSecs()For Local i:Int = 0 Until runs result :+ Com2(i, 3)NextPrint "result " + result + " in " + (MilliSecs()-t)+"ms.   Derrons WOW 56ms!"result = 0t = MilliSecs()For Local i:Int = 0 Until runs result :+ Com3(i, 3)NextPrint "result " + result + " in " + (MilliSecs()-t)+"ms.   Baggeys"result = 0t = MilliSecs()For Local i:Int = 0 Until runs result = result + i ~ (1 Shl 3 - 1)NextPrintPrint "result " + result + " in " + (MilliSecs()-t)+"ms.   No Function Call!"`
Conclusion. I suppose that unless we understand how the Blitzmax compiler works. We would not necessarily know which things to do, to get the best speeds/results anyways

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

#### Midimaster

I run your example and got this results:
`result 887459712 in 10ms.   Midimastersresult 887459712 in 10ms.   Derrons result 887459712 in 57ms.   Baggeysresult 887459712 in 60ms.   No Function Call`
...back from Egypt

#### col

#6
This applies to all programming languages, and your its your algorithms and logic that matter the most.

A good rule of thumb would be to always try to use the correct datatypes for your goal. using strings to do bit manipulation is a no-no in anywlanguage.

The optimisation that Derron speaks of, the '(1 shl 3 - 1)' would be optimised by the backend c compiler even if the 'max converter to c didn't do it, so yeah I wouldn't worry so much unless you have issues.
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

#### Baggey

Quote from: Midimaster on October 08, 2023, 12:56:58I run your example and got this results:
`result 887459712 in 10ms.   Midimastersresult 887459712 in 10ms.   Derrons result 887459712 in 57ms.   Baggeysresult 887459712 in 60ms.   No Function Call`
On my PC i get

`result 887459712 in 926ms.   Midimastersresult 887459712 in 57ms.   Derrons WOW 56ms!result 887459712 in 236ms.   Baggeysresult 887459712 in 55ms.   No Function Call!Process complete`
Im Running Windows 10?

So Maybe the type of setup we have ie, 32 bit or 64 bit, Linux, Mac etc may have something todo with the different results oh im on 50Hz, 240v here?
Maybe what runs quicker on my system may not on someone else's hmm

As always, I appreciate anyone's help and will not take any offence to criticisms or idea's. Im here to learn and perfect my coding.

As we say there are more way's than one to skin a cat!? It don't sound right really but that's what we say here.

Kindest Regards to anyone who try to help me! Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 24GB ram 1TB SSD and NVIDIA Quadro K620 . DID Technology stop! Or have we been assimulated!

ZX Spectrum 48k, C64, ORIC Atmos 48K, Enterprise 128K, The SID chip. Im Misunderstood!

#### Baggey

Quote from: col on October 08, 2023, 13:42:26