Qbasicnews.com
April 07, 2020, 11:47:11 PM
 Welcome, Guest. Please login or register. 1 Hour 1 Day 1 Week 1 Month Forever Login with username, password and session length
 Home Help Search Login Register
 Pages: [1]
 Author Topic: Opposite of HEX\$ in Qbasic?  (Read 9074 times)
mycophobiac
New Member

Posts: 17

 « on: September 04, 2004, 04:48:54 PM »

I am making a BMP load/save program in QB, and I need a way to convert hexadecimal values from an opened file to decimal numbers. I know of the HEX\$ function that can do the exact opposite, but there does not seem to be a similar function to that built in to QB. I'd rather not make my own hex>dec function if I can help it. Any suggestions?
 Logged

img]http://b.domaindlx.com/cygh/mycophob3.gif[/img]
v3cz0r
I hold this place together

Posts: 924

 « Reply #1 on: September 04, 2004, 04:52:46 PM »

VAL does that, just prefix the string with a "&H".. decnum% = val( "&H" + hexnum\$ )
 Logged

Neo
Na_th_an

Posts: 2150

 « Reply #2 on: September 05, 2004, 08:52:09 AM »

I'm just dropping in here when the answer is already given (which I also knew).

But this seems kind of interesting: how about the reversal of OCT\$, I've always coded that function myself and I couldn't find any function that reverses it. I think there isn't so such thing as &O right?
 Logged
Nemesis
Forum Regular

Posts: 118

 « Reply #3 on: September 05, 2004, 12:59:00 PM »

Quote from: "Neo"
I'm just dropping in here when the answer is already given (which I also knew).

But this seems kind of interesting: how about the reversal of OCT\$, I've always coded that function myself and I couldn't find any function that reverses it. I think there isn't so such thing as &O right?

D\$="10":O=VAL("&O"+D\$):CLS:?O

It works for me
 Logged
whitetiger0990
__/--\__

Posts: 2964

 « Reply #4 on: September 05, 2004, 01:30:58 PM »

Wow what do you know. I never knew that existed.
 Logged

[size=10]Back by popular demand!
I will byte and nibble you bit by bit until nothing remains but crumbs.[/size]
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #5 on: September 08, 2004, 05:56:21 PM »

Nemesis:
Wrong thread, you should be posting to  the obfuscated code challenge
That CLS just before the end is perfect!!!
 Logged

Antoni
Wizard Genius
Member

Posts: 57

 « Reply #6 on: September 29, 2004, 04:51:24 PM »

I didn't know there was an obfuscated qbasic code contest... hmmm, maybe i should make one... anyways, here's code to convert back and forth between octal or hex. Note that octal and hex numbers are stored as strings:

Code:

'For some reason I decided to put the octal first, don't ask why...
octalnum\$ = OCT\$(decimalnum%)
octalnum\$ = "&O" + octalnum\$
decimalnum% = VAL(octalnum\$)
hexnum\$ = HEX\$(decimalnum%)
hexnum\$ = "&H" + hexnum\$
decimalnum% = VAL(hexnum\$)
'And here's a bit of code to convert your own hexadecimal number:
hexnum\$ = "&HFF"
decimalnum% = VAL(hexnum\$)
'decimalnum% should now be equal to 255. You should be able to
'test this by PRINTing the numbers, like this:
PRINT "Hex num: ";
PRINT hexnum\$
PRINT "Decimal Equivalent: ";
PRINT STR\$(decimalnum%)

I used this kind of code to write a hexadecimal/octal calculator once. Those are useful. It even PRINTed the associated ASCII character too! Note: For un-named hex or octal constants in the place of a decimal number, the quotation marks are not required. For example, you can type:

Code:

'Notice no quotation marks surrounding the &H14:
thenum = &H14 - 1

What we really need is some sort of function that can convert a number from any base to any base. It would look like this:

FUNCTION BASECONV\$(basefrom, baseto, numfrom\$)

where basefrom would be the base which numfrom\$ is represented in, any number from 2 (binary) to 36. 16 would be hexadecimal, 8 octal, and 10 decimal. The same for baseto. The value returned would be a string that could be converted back by calling the function again. Like this:

base18\$ = BASECONV\$(10, 18, "12")
base10\$ = BASECONV\$(18, 10, base18\$)

Here are the bases:

Code:

2 (Binary)
01
3
012
4
0123
5
01234
6
012345
7
0123456
8 (Octal)
01234567
9
012345678
10 (Decimal)
0123456789
11
0123456789A
12
0123456789AB
13
0123456789ABC
14
0123456789ABCD
15
0123456789ABCDE
0123456789ABCDEF
...
all the way to base
36
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

Good luck!
 Logged

rogramming is like life - you work first, then play. :bounce: :rotfl: :bounce: :rotfl: :bounce: :rotfl: :bounce: :rotfl: :bounce: :rotfl: :bounce: :rotfl: :bounce:
oracle
*/-\*

Posts: 3652

 « Reply #7 on: September 30, 2004, 08:46:18 PM »

There's one at QBNZ somewhere...
 Logged

Moneo
Na_th_an

Posts: 1971

 « Reply #8 on: October 02, 2004, 12:53:42 AM »

Wonder where Octal and Hex come from?

Before the IBM 360 came out about 1963, everything was BCD and Octal.

BCD (Binary Coded Decimal) was generally 6 bits, although some called the 4 bit version for representing 0 to 9, BCD also. This was used on character oriented machines. Some older character machines used codes like "2 out of 5", where only 2 of the 5 bits could be on at any given time.

OCTAL was used on the binary (not character oriented) machines. Octal was very popular. You could take a string of bits, usually the size of the machine's registers, and print out the registers and memory locations grouping the bits (usually from right to left) 3 at a time, giving values from 0 to 7, that is, to the base 8. "Octo" in Greek means eight. Some programmers got real good at adding and subtracting Octal values.

BYTE-OCTAL also known as 3-3-2:
When codes went to 8 bits, ASCII and EBCDIC, just before the IBM 360 came out, programmers represented the eight bits in Byte-Octal, due to their Octal experience. However, 3 doesn't go evenly into 8, so they just did not include the extra bit and used 3 bits, 3 bits, and 2 bits. Depending on the meaning of the byte, the extra bit was either not included in front or back.

HEX or HEXADECIMAL NOTATION came out with the IBM 360. It was the same 8-bit byte as Byte Octal but grouped 4 bits as a time, with no bit allignment problems. The problem with this base 16 code is that single position values go from 0 to F, where A thru F covers 10 thru 15. Not as easy as Octal to add/subt by hand.
*****
 Logged
marinedalek
Forum Regular

Posts: 123

 « Reply #9 on: October 26, 2004, 06:10:51 PM »

[syntax="qbasic"]
'Omni-base converter
'Peter O'Rourke (Marinedalek) 2004
DECLARE FUNCTION reverse\$ (text\$)
DECLARE FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)
DIM SHARED digitarray AS STRING * 36
digitarray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CLS
PRINT baseconv\$(16, 2, "FFFF")

FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)
IF baseto% <= 1 OR basefrom% < 1 OR baseto% > 36 OR basefrom% > 36 THEN baseconv\$ = "0": EXIT FUNCTION
FOR position% = LEN(numfrom\$) TO 1 STEP -1
tempdec& = tempdec& + (basefrom% ^ (LEN(numfrom\$) - position%)) * (INSTR(digitarray, MID\$(numfrom\$, position%, 1)) - 1)
NEXT position%
IF baseto% = 10 THEN
baseconv\$ = LTRIM\$(STR\$(tempdec&)) 'skip last calculation if destination is
'decimal - it 'd be a waste of time.
ELSE
DO
tempdest\$ = MID\$(digitarray, (tempdec& MOD baseto%) + 1, 1) + tempdest\$
tempdec& = tempdec& \ baseto%
LOOP UNTIL tempdec& = 0
baseconv\$ = tempdest\$
END IF
END FUNCTION

FUNCTION reverse\$ (text\$)
FOR i% = LEN(text\$) TO 1 STEP -1
temptxt\$ = temptxt\$ + MID\$(text\$, i%, 1)
NEXT i%
reverse\$ = temptxt\$
END FUNCTION

[/syntax]

Any feedback?
 Logged

8% of the teenage population smokes or has smoked pot. If you're one of the 2% who hasn't, copy and paste this in your signature.
Moneo
Na_th_an

Posts: 1971

 « Reply #10 on: October 30, 2004, 03:22:08 PM »

Quote from: "marinedalek"
[syntax="qbasic"]
'Omni-base converter
'Peter O'Rourke (Marinedalek) 2004
DECLARE FUNCTION reverse\$ (text\$)
DECLARE FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)
DIM SHARED digitarray AS STRING * 36
digitarray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CLS
PRINT baseconv\$(16, 2, "FFFF")

FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)
IF baseto% <= 1 OR basefrom% < 1 OR baseto% > 36 OR basefrom% > 36 THEN baseconv\$ = "0": EXIT FUNCTION
FOR position% = LEN(numfrom\$) TO 1 STEP -1
tempdec& = tempdec& + (basefrom% ^ (LEN(numfrom\$) - position%)) * (INSTR(digitarray, MID\$(numfrom\$, position%, 1)) - 1)
NEXT position%
IF baseto% = 10 THEN
baseconv\$ = LTRIM\$(STR\$(tempdec&)) 'skip last calculation if destination is
'decimal - it 'd be a waste of time.
ELSE
DO
tempdest\$ = MID\$(digitarray, (tempdec& MOD baseto%) + 1, 1) + tempdest\$
tempdec& = tempdec& \ baseto%
LOOP UNTIL tempdec& = 0
baseconv\$ = tempdest\$
END IF
END FUNCTION

FUNCTION reverse\$ (text\$)
FOR i% = LEN(text\$) TO 1 STEP -1
temptxt\$ = temptxt\$ + MID\$(text\$, i%, 1)
NEXT i%
reverse\$ = temptxt\$
END FUNCTION

[/syntax]

Any feedback?

Yes, some feedback on your coding style:
Code:

DIM SHARED digitarray AS STRING * 36
digitarray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

Why the fixed length string? What's wrong with just plain
Code:

dim shared digitarray\$
digitarray\$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

On the other hand your code is full of explicit parameter type assignments like %, &. Example:
Code:

tempdec& = tempdec& \ baseto%

This makes code error prone and also hard to read. Define your variable types up fron in the program with DIMs.

You got all the latest color goodies, but your coding structure regarding indentation is not good. Example:
Code:

FOR i% = LEN(text\$) TO 1 STEP -1
temptxt\$ = temptxt\$ + MID\$(text\$, i%, 1)
NEXT i%

As far as the technical merit of your code, I'll need to test it when I have time.
*****
 Logged
*/-\*

Posts: 3655

 « Reply #11 on: October 30, 2004, 03:31:07 PM »

Maybe he has a purpose for shared variables? Who knows. Also, there's nothing wrong with fixed-length strings...everyone codes differently, thankfully there's no real "right or wrong" coding style as long as the job gets done.
 Logged

I'd knock on wood, but my desk is particle board.
Moneo
Na_th_an

Posts: 1971

 « Reply #12 on: October 30, 2004, 03:54:26 PM »

Maybe he has a purpose for shared variables? Who knows. Also, there's nothing wrong with fixed-length strings...everyone codes differently, thankfully there's no real "right or wrong" coding style as long as the job gets done.

You read my post before I was finished editing it. I removed the comment about SHARED when I realized that the shared variable was used inside of a function. Actually it should have been set up as a CONST which would automatically make is shared.

I personnally never use fixed length strings because the variable name without the trailing \$ can be confused with a numeric variable, plus the fact that I find no real "need" to use them.

Yes, personal coding styles are fine, as long as they make things clear for the next programmer who takes over the program. Nobody pays much attention to this "next programmer" issue. I spent 7 years at McGraw-Hill where about 70% of my time was spent fixing and retrofitting existing PickBasic programs of a huge ERP system called CISPUB that they had purchased just before I got there. After this experience, you appreciate clear, understandable code.
*****
 Logged
marinedalek
Forum Regular

Posts: 123

 « Reply #13 on: October 31, 2004, 06:23:05 AM »

hmm.. don't know how that reversal routine found it's way in there... Normally I do indent the contents of FOR-NEXT loops, I must have forgotten. Here's a version that conforms to your "style"   (I have kept all the veriables passed through to the function complete with their trailing %. It'll be a cold day in hell before I stop  :wink:  .

[syntax="qbasic"] 'Omni-base converter v0.2
'Peter O'Rourke (Marinedalek) 2004
DECLARE FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)
DIM tempdec AS LONG

CONST digitarray\$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CLS
PRINT baseconv\$(16, 2, "FFFF")

FUNCTION baseconv\$ (basefrom%, baseto%, numfrom\$)

'Next line exits the sub if an invalid base is given
IF baseto% <= 1 OR basefrom% < 1 OR baseto% > 36 OR basefrom% > 36 THEN baseconv\$ = "0": EXIT FUNCTION

'This FOR-NEXT loop converts numfrom\$ into decimal for conversion to the specified base
FOR position% = LEN(numfrom\$) TO 1 STEP -1
tempdec = tempdec + (basefrom% ^ (LEN(numfrom\$) - position%)) * (INSTR(digitarray\$, MID\$(numfrom\$, position%, 1)) - 1)
NEXT position%

IF baseto% = 10 THEN
baseconv\$ = LTRIM\$(STR\$(tempdec)) 'skip last calculation if destination is
'decimal - it'd be a waste of time.
ELSE
'This section converts the decimal number into the specified base
DO
tempdest\$ = MID\$(digitarray\$, (tempdec MOD baseto%) + 1, 1) + tempdest\$
tempdec = tempdec \ baseto%
LOOP UNTIL tempdec = 0
baseconv\$ = tempdest\$
END IF
END FUNCTION

[/syntax]
 Logged

8% of the teenage population smokes or has smoked pot. If you're one of the 2% who hasn't, copy and paste this in your signature.
 Pages: [1]