Page 1 of 3

some c code

Posted: Mon Aug 08, 2005 2:20 pm
by SebMcClouth
Who knows some C?? I need to know what this does:

Code: Select all

((val)=((val)&15) + ((val)>>4)*10)
grtz

Seb

Posted: Mon Aug 08, 2005 2:26 pm
by MystikShadows
((val)=((val)&15) + ((val)>>4)*10)

Tests if Val = Val And 15 (inary logical operation) + Val (>> is shift bits rights 4 position) * 10

Posted: Mon Aug 08, 2005 2:28 pm
by SebMcClouth
Okay, and what if the code is like this:

Code: Select all

#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
grtz
Seb

Posted: Mon Aug 08, 2005 2:57 pm
by MystikShadows
The #define creates a function called BCD_TO_BIN which is equal to everthing on the right side

This is done when a set of instructions are going to be called often in the module.

The QB equivalent of that is a function really.

Posted: Mon Aug 08, 2005 3:02 pm
by SebMcClouth
So... what would this code be in qb?

grtz
Seb

Posted: Mon Aug 08, 2005 3:04 pm
by MystikShadows
I dont' believe you can do it in QB...atleat I'm not sure how the Bit Shift Right with be performed...I'll let someone else answer that :-).

FreeBasic has the SHL and SHR bit shifters, but I'm not sure about QB.

Posted: Mon Aug 08, 2005 3:06 pm
by SebMcClouth
What's bit shifting?

grtz
Seb

Posted: Mon Aug 08, 2005 3:12 pm
by MystikShadows
Bit shift is done at the binary level. for example, if you have the following bynary value:

00000001 and you bitshift this 4 positions to the left, you'd have
00010000 if you bit shift that valur right 4 positions, you'd have
00000001 agauin. you're shifting bits left and right :-).

Posted: Mon Aug 08, 2005 3:15 pm
by SebMcClouth
You have to bring e.g 8 back to
1000 and then according to val>>4 it would 0001 or 1?

correct?

grtz
Seb

Posted: Mon Aug 08, 2005 3:52 pm
by Wyndo
There has to be a quicker, less clunky way of doing it, but I wrote a bit of code below that does the trick. It works for 32 bits shifting left (the leftmost bit is lost), and 31 bits shifting right (the rightmost bit is lost, and the leftmost bit is ignored due to the way I'm handling it). It might give you an idea about how to write the functions more efficiently, at least. Both BitLeft and BitRight accept two parameters -- the number to shift, and the number of bits to *be* shifted. In the example, I shift 1234567 left 2 places, print the result, then shift it back right 2 places. You can see the original number then. Like I said, it works with more bits, but "print" seems to want to show scientific notation, and I've forgotten how to prevent that.

Anyway, enjoy.

-------------

Code: Select all

DECLARE FUNCTION BitRight! (value!, tm)
DECLARE FUNCTION BitLeft! (value!, tm)

CLS
x! = BitLeft(1234567, 2)
PRINT x!
y! = BitRight(x!, 2)
PRINT y!

FUNCTION BitLeft (value!, tm)
    DIM Newval!, TempVal!, x, y, z
    TempVal! = value!
    FOR y = 1 TO tm
        Newval! = 0: z = 1
        FOR x = 1 TO 31 'Leftmost bit #32 lost.
            IF (TempVal! AND z) THEN
                Newval! = Newval! + (z * 2)
            END IF
            z = z * 2 'Next bit over.
        NEXT x
        TempVal! = Newval!
    NEXT y
    BitLeft = TempVal!
END FUNCTION

FUNCTION BitRight (value!, tm)
    DIM Newval!, TempVal!, x, y, z
    TempVal! = value!
    FOR y = 1 TO tm
        Newval! = 0: z = 1073741824
        'My method won't work if number is full 32-bit...
        'because QB will overflow on the starting number.
        FOR x = 1 TO 30 'Rightmost bit #1 lost.
            IF (TempVal! AND z) THEN
                Newval! = Newval! + (z / 2)
            END IF
            z = z / 2 'Next bit over.
        NEXT x
        TempVal! = Newval!
    NEXT y
    BitRight = TempVal!
END FUNCTION

Posted: Mon Aug 08, 2005 3:54 pm
by MystikShadows
SebMcClouth wrote:You have to bring e.g 8 back to
1000 and then according to val>>4 it would 0001 or 1?

correct?

grtz
Seb
Yes

Posted: Mon Aug 08, 2005 3:57 pm
by Wyndo
To write your function, it would look like this. *Hopefully* this is right. Try it and see.

Code: Select all

'Based on:
'#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)

FUNCTION BCD_TO_BIN(value!)
    BCD_TO_BIN = (value! AND 15) + (BitRight(value!,4)*10)
END FUNCTION
The only other difference is that the C Macro is actually setting the value of whatever you pass in, without having to code it. In other words, you could do this in C:

Code: Select all

long x=1234;
BCD_TO_BIN(x);
Which in my QB sample you'd have to write like this:

Code: Select all

DIM x as LONG: x=1234
x=BCD_TO_BIN(x)
'or just x=BCD_TO_BIN(1234)

Posted: Mon Aug 08, 2005 4:00 pm
by SebMcClouth
Okay I still need some help but this is how far we got:

Code: Select all

DECLARE FUNCTION BitRight! (value!, tm) 
DECLARE FUNCTION BitLeft! (value!, tm) 
DECLARE FUNCTION BCD2BIN (val)

FUNCTION BCD2BIN (VAL)
'((val)=((val)&15) + ((val)>>4)*10)
BCD2BIN=(val...
END Function

FUNCTION BitLeft (value!, tm) 
    DIM Newval!, TempVal!, x, y, z 
    TempVal! = value! 
    FOR y = 1 TO tm 
        Newval! = 0: z = 1 
        FOR x = 1 TO 31 'Leftmost bit #32 lost. 
            IF (TempVal! AND z) THEN 
                Newval! = Newval! + (z * 2) 
            END IF 
            z = z * 2 'Next bit over. 
        NEXT x 
        TempVal! = Newval! 
    NEXT y 
    BitLeft = TempVal! 
END FUNCTION 

FUNCTION BitRight (value!, tm) 
    DIM Newval!, TempVal!, x, y, z 
    TempVal! = value! 
    FOR y = 1 TO tm 
        Newval! = 0: z = 1073741824 
        'My method won't work if number is full 32-bit... 
        'because QB will overflow on the starting number. 
        FOR x = 1 TO 30 'Rightmost bit #1 lost. 
            IF (TempVal! AND z) THEN 
                Newval! = Newval! + (z / 2) 
            END IF 
            z = z / 2 'Next bit over. 
        NEXT x 
        TempVal! = Newval! 
    NEXT y 
    BitRight = TempVal! 
END FUNCTION
How can I then move this:

Code: Select all

((val)=((val)&15) + ((val)>>4)*10)
Into:

Code: Select all

((val)=((val)&15)+(BitRight(val),4)*10)
grtz

(heheh we wrote it at the same time)

Posted: Mon Aug 08, 2005 4:03 pm
by Wyndo
I made a change to BCD_TO_BIN when I remembered "val" is a reserved word in QB. Try the edited version directly above your prior message, and that *should* do the same thing as your C Macro. Compare the results to know for sure.

Posted: Mon Aug 08, 2005 4:11 pm
by SebMcClouth
Will test is later... I copied it in the file which I'm going to test with... btw I changed BCD_TO_BIN in BCD2BIN, since qb 4.5 doesn't coop with _.

grtz
Seb

Posted: Mon Aug 08, 2005 4:12 pm
by Wyndo
Woops. I forgot about that. I did test BitLeft and BitRight, but I was just winging it on BCD_TO_BIN. Sorry about that. I haven't used QB much in several years. Also, for your example, you only need BitRight. It doesn't look like BitLeft is used, unless you need it for something else later.

Posted: Mon Aug 08, 2005 5:40 pm
by {Nathan}
I havn't seen you here before, Wyndo, so...

WELCOME TO THE...

FORUM OF...
HELL

J/k welcome... *evil laugh*
:twisted: :twisted: :twisted: :twisted: :twisted: :twisted: :twisted: :twisted: :twisted:

EDIT: In case if you didn't know it, I changed my sig 8)

Posted: Tue Aug 09, 2005 1:36 am
by SebMcClouth
I'm gonna keep bitleft and right in the core... you never know where it might be good for... ofcourse I'll give ya credit.

grtz
Seb

Posted: Tue Aug 09, 2005 2:23 am
by SebMcClouth
I've tested it, and it works. Another linux mystery solved. Okay. Now I'm gonna present ya some where it has to work with and the problem I have afterwards (not with the code you supplied). Remember it's C-converted-to-QB so most of it might be wrong but I'm not a C-programmer, I can just read it a bit.

Code: Select all

TYPE tm
Sec as integer
Min as integer
Hour as integer
mDay as integer
Mon as integer
Year as integer
wDay as integer
yDay as integer
Isdst as integer
end type

DIM SHARED tmtime as tm

CLS

TimeInit

PRINT tmtime.Hour; tmtime.Min; tmtime.Sec
PRINT tmtime.Mday; tmtimeMon; tmtime.Year

FUNCTION BCD2BIN (Value!)  
BCD2BIN=(Value! and 15)+(BitRight(Value!,4)*10)
END Function 

FUNCTION BitLeft (value!, tm) 
    DIM Newval!, TempVal!, x, y, z 
    TempVal! = value! 
    FOR y = 1 TO tm 
        Newval! = 0: z = 1 
        FOR x = 1 TO 31 'Leftmost bit #32 lost. 
            IF (TempVal! AND z) THEN 
                Newval! = Newval! + (z * 2) 
            END IF 
            z = z * 2 'Next bit over. 
        NEXT x 
        TempVal! = Newval! 
    NEXT y 
    BitLeft = TempVal! 
END FUNCTION 

FUNCTION BitRight (value!, tm) 
    DIM Newval!, TempVal!, x, y, z 
    TempVal! = value! 
    FOR y = 1 TO tm 
        Newval! = 0: z = 1073741824 
        'My method won't work if number is full 32-bit... 
        'because QB will overflow on the starting number. 
        FOR x = 1 TO 30 'Rightmost bit #1 lost. 
            IF (TempVal! AND z) THEN 
                Newval! = Newval! + (z / 2) 
            END IF 
            z = z / 2 'Next bit over. 
        NEXT x 
        TempVal! = Newval! 
    NEXT y 
    BitRight = TempVal! 
END FUNCTION

FUNCTION CMOSRead (addr)
out &h70, addr
CMOSRead=inp(&h71)
END FUNCTION

SUB TimeInit
	do 
		tmtime.sec = CMOSREAD(0)
		tmtime.min = CMOSREAD(2)
		tmtime.hour = CMOSREAD(4)
		tmtime.mday = CMOSREAD(7)
		tmtime.mon = CMOSREAD(8)-1
		tmtime.year = CMOSREAD(9)
	loop while (tmtime.sec = CMOSREAD(0))
	BCD2BIN(tmtime.sec)
	BCD2BIN(tmtime.min)
	BCD2BIN(tmtime.hour)
	BCD2BIN(tmtime.mday)
	BCD2BIN(tmtime.mon)
	BCD2BIN(tmtime.year)
	startuptime = mktime(&time)
END SUB
mktime is a function. How can I build startuptime with mktime, if mktime has to build it with tmtime? Can I pass tmtime to mktime?

grtz
Seb

Posted: Tue Aug 09, 2005 7:08 am
by Wyndo
Something may be missing. Have you coded "mktime" into QB? The call to it still looks like C code. Also, those BCD2BIN calls will have to be changed to value=BCD2BIN(value) in order to work right. As for passing a variable by reference instead of by value, I don't remember how to do this with QB -- if it can even be done. Maybe somebody else can answer.