Qbasicnews.com

QBasic => QB Discussion & Programming Help => Topic started by: mycophobiac on September 04, 2004, 04:48:54 PM



Title: Opposite of HEX$ in Qbasic?
Post by: mycophobiac 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?


Title: Opposite of HEX$ in Qbasic?
Post by: v3cz0r on September 04, 2004, 04:52:46 PM
VAL does that, just prefix the string with a "&H".. decnum% = val( "&H" + hexnum$ )


Title: Opposite of HEX$ in Qbasic?
Post by: Neo 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? :D


Title: Opposite of HEX$ in Qbasic?
Post by: Nemesis 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


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

It works for me  :)


Title: Opposite of HEX$ in Qbasic?
Post by: whitetiger0990 on September 05, 2004, 01:30:58 PM
Wow what do you know. I never knew that existed.


Title: Opposite of HEX$ in Qbasic?
Post by: Antoni Gual on September 08, 2004, 05:56:21 PM
Nemesis:
Wrong thread, you should be posting to  the obfuscated code challenge  :D
That CLS just before the end is perfect!!!


Title: LOL
Post by: Wizard Genius 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$)
'Here's the hexadecimal...
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
16 (Hexadecimal)
0123456789ABCDEF
...
all the way to base
36
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ


Good luck! 8)


Title: Opposite of HEX$ in Qbasic?
Post by: oracle on September 30, 2004, 08:46:18 PM
There's one at QBNZ somewhere...


Title: Opposite of HEX$ in Qbasic?
Post by: Moneo 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.
*****


Title: Opposite of HEX$ in Qbasic?
Post by: marinedalek on October 26, 2004, 06:10:51 PM
How about this? :D
[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?


Title: Opposite of HEX$ in Qbasic?
Post by: Moneo on October 30, 2004, 03:22:08 PM
Quote from: "marinedalek"
How about this? :D
[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.
*****


Title: Opposite of HEX$ in Qbasic?
Post by: adosorken on October 30, 2004, 03:31:07 PM
Maybe he has a purpose for shared variables? Who knows. :D 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. :D


Title: Opposite of HEX$ in Qbasic?
Post by: Moneo on October 30, 2004, 03:54:26 PM
Quote from: "adosorken"
Maybe he has a purpose for shared variables? Who knows. :D 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. :D

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.
*****


Title: Opposite of HEX$ in Qbasic?
Post by: marinedalek 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"  :D (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]