Solved

CVS & MKS$

Posted on 1997-06-27
14
1,187 Views
Last Modified: 2008-03-06
What's the mathematical formula behind the conversion for
BASIC CVS function and vice versa, MKS$.

CVS converts a single precision number to a 4-byte string
and MKS$ does the reverse.

Some results using the functions:

10 F2 6C 94 (HEX) ==  970529 (DEC)
80 80 80 80 (HEX) ==  -0.501961 (DEC)
A0 B0 C0 D0 (HEX) ==  -9.09953e+23 (DEC)
12 34 56 78 (HEX) ==  0.00326848 (DEC)
98 76 54 32 (HEX) ==  2.74602e-24 (DEC)
0
Comment
Question by:gangclar
  • 8
  • 6
14 Comments
 
LVL 5

Accepted Solution

by:
y96andha earned 50 total points
ID: 1427804
Here is a function which you can substitute for CVS. It's not written in Visual Basic, but rather in QBasic, as that was the language where I found the CVS and MKS$ functions.

I hope you can read the code and understand how it works.

You should be able to construct the inverse function from this source.

Please comment if you have any questions.

FUNCTION f (a AS STRING)
        g = (ASC(MID$(a, 3)) AND &H7F) / 2 ^ 7
        g = g + ASC(MID$(a, 2)) / 2 ^ 15
        g = g + ASC(MID$(a, 1)) / 2 ^ 23
        f = (1 - ((ASC(MID$(a, 4)) AND 128) / 64)) * (1 + g) * 2 ^ ((ASC(MID$(a, 4)) AND &H7F) * 2 + ((ASC(MID$(a, 3)) AND 128) / 128) - &H7F)
END FUNCTION

0
 

Author Comment

by:gangclar
ID: 1427805
It would be kind if you can explain the mathematics behind CVS
function using plain English. Actually I wanted to write a
similar function in C to convert data that was stored by program
written in Basic using the MKS$ function.

I would try to read the program that you've listed. Thanks.
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427806
OK. I could translate the code directly into C:

char a[4];
float g,f;
int e;
g=(a[2] & 0x7f) / (float)0x80;
g+=a[1] / (float)0x8000l;
g+=a[0] / (float)0x800000l;
e=((a[3] & 0x7f) << 1) + ((a[2] >>7) & 1) - 0x7f;
f=(1+g) * pow(2,e);
if(a[3] & 0x80)
    f=-f;

Untested code, but should work.

Plain English explanation:

Name the bytes in the string A, B, C, D. Bit 0 of byte A is called A0, and so on.

The number is written in binary form.

The mantissa is (binary):
1 C6 C5 ... C0 B7 B6 ... B0 A7 ... A0

The decimal point of the mantissa is after the first digit (after the 1).

The sign of the mantissa is stored in D7, 1 means negative.

The value of
   D6 D5 ... D0 C7
is the exponent added with 7F hexadecimal.


I hope you can understand my explanation. English is not my native language.


0
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

Author Comment

by:gangclar
ID: 1427807
I do understand what you're saying, you wrote clear sentences
*8-).

However, I do have doubts immediately after reading your
comment. It would be great if you can explain an example or so.
Let me quote the example 10 F2 6C 94 (HEX).

According to what I understood from your explaination, byte D in
this case is 94(HEX) and D7(bit 7) would be 1, which tells that
this number is negative. But the conversion ended as +970529.

It would really help if you can list the working to convert the
above 4 bytes string to 970529(DEC). Thanks again !
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427808
You have made a mistake when typing in that value. I didn't get it to fit the description either, so I tested it in QBasic. The correct value is 10 F2 6C 49. You have mixed up the last two digits.

0
 

Author Comment

by:gangclar
ID: 1427809
I've tried the C program that you've drafted. It doesn't produce the correct value. I used QBASIC CVS function to convert the value 970529 (DEC) and it gave me the 4-byte string 10 F2 6C 94 (HEX). The drafted program gave me -1.191478e-26 for the hex value quote above. I used Turbo C v3.0

Could you kindly provide me some help or reference to understand the mathematical logic of BASIC CVS and MKS$ function ? Thanks in advance.
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427810
I don't seem to get the same results. What version of QBasic are you using? I use the one that comes with Win95.

Executing this line results in 970529 as output from my QBasic interpreter:

PRINT CVS(CHR$(&H10) + CHR$(&HF2) + CHR$(&H6C) + CHR$(&H49))

If our Basic versions doesn't produce the same results, I'm afraid I cannot help you. I can only tell you how the one I have works.

0
 

Author Comment

by:gangclar
ID: 1427811
I just managed to clear the air. For MS QBasic, please use CVSMBF instead of CVS which works for MS GWBasic. I tried on my copy of QBasic under WIN 95 and the results are produced correctly using CVSMBF.

Could you enlighten me on the conversion using C ? Thanks again !
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427812
OK, I don't have any good manual for this function, so I've analyzed it. This is my theory: (I copied most of it from above and then changed some of it)

Plain English explanation:

Name the bytes in the string A, B, C, D. Bit 0 of byte A is called A0, and so on.

The number is written in binary form.

The mantissa is (binary):
1 C6 C5 ... C0 B7 B6 ... B0 A7 ... A0

The decimal point of the mantissa is after the first digit (after the 1).

The sign of the mantissa is stored in C7, 1 means negative.

The value of
  D7 D6 D5 ... D0
is the exponent added with 81 hexadecimal.

I hope this is correct, I'll try and make some C code to test it.
0
 

Author Comment

by:gangclar
ID: 1427813
I tried on the drafted program that you've suggested. By changing 10 F2 6C 94 to 10 F2 6C 49, I still don't get 970529.

I'm at my wits' end and look forward for your good news. Thanks again.
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427814
This is tested code to print 970529 with the CVSMBF format

static unsigned char a[4] = {0x10, 0xf2, 0x6c, 0x94};
float g,f;
int e;

g=(a[2] & 0x7f) / (float)0x80;
g+=a[1] / (float)0x8000l;
g+=a[0] / (float)0x800000l;
e=a[3] - 0x81;
f=(1+g) * pow(2,e);
if(a[2] & 0x80)
      f=-f;
printf("%g", f);


This is tested code to print 970259 with the CVS format

static unsigned char a[4] = {0x10, 0xf2, 0x6c, 0x49};
float g,f;
int e;


g=(a[2] & 0x7f) / (float)0x80;
g+=a[1] / (float)0x8000l;
g+=a[0] / (float)0x800000l;
e=((a[3] & 0x7f) << 1) + ((a[2] >>7) & 1) - 0x7f;
f=(1+g) * pow(2,e);
if(a[3] & 0x80)
      f=-f;
printf("%g", f);



0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427815
Sorry, made an error in the last description, it should of course be 970529 there too.
0
 

Author Comment

by:gangclar
ID: 1427816
I've tried the suggested codes using Turbo C v3.0. However, the result of conversion for 10 F2 6C 94 was 966898.1. Is there anything that I missed out ? Thanks again.
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427817
Now I've found the error. You typed in the code manually instead of copying it? The values of 0x8000l and 0x800000l are 0x8000 and 0x800000 respective, the last character is an L, for long constant.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Determine Range to Select 5 52
Access 2013 combo box not working 3 51
Add a task in Outlook from access 11 42
How to read File Date Created using VB6 8 51
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question