Solved

CVS & MKS$

Posted on 1997-06-27
14
1,167 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 

Author Comment

by:gangclar
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:gangclar
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Sorry, made an error in the last description, it should of course be 970529 there too.
0
 

Author Comment

by:gangclar
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now