Qbasicnews.com
July 06, 2020, 08:04:09 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Opposite of HEX$ in Qbasic?  (Read 9262 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



WWW
« 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? Cheesy
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? Cheesy


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

It works for me  Smiley
Logged
whitetiger0990
__/--\__
*****
Posts: 2964



WWW
« 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



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

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

Antoni
Wizard Genius
Member
*
Posts: 57


WWW
LOL
« 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$)
'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! Cool
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



WWW
« 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


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

How about this? Cheesy
[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"
How about this? Cheesy
[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
adosorken
*/-\*
*****
Posts: 3655



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

Maybe he has a purpose for shared variables? Who knows. Cheesy 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. Cheesy
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 »

Quote from: "adosorken"
Maybe he has a purpose for shared variables? Who knows. Cheesy 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. Cheesy

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


WWW
« 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"  Cheesy (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]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!