Results 1 to 9 of 9

Thread: Transfer LONG to SINGLE (and vice versa) with pure math.

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Transfer LONG to SINGLE (and vice versa) with pure math.

    Hi folks. This is a challenge I've wrestled with a bit and can't find an answer. I'll admit up-front that it's really for a little C based macro language I play with, but the concept is exactly the same for VB6, so I've framed the question in terms of VB6. However, I need to make some restrictions so the concept will port over. So, first off, no API calls to RtlCopyMemory, PutMem4, or GetMem4 (or other API copy memory calls). Also, no use of LSET, RSET, or aliasing tricks. In other words, it pretty much has to be pure math (or possibly something else I haven't considered).

    Ok, here's the challenge. I'd like to take a LONG and put it into a SINGLE (and vice versa), and always have it completely perfectly reversible, and never have an error, regardless of the value of the initial LONG. In other words, every possible LONG value has to work. I don't care if the actual bits stay in the same order in the SINGLE, but it's still got to be reversible.

    Yes, it's trivially easy with RtlCopyMemory because each is just 4 bytes (32 bits). So, the bits are certainly there. For those whose interest is piqued, I'll tell you my stumbling blocks. I can work out the math for about 31.9 of the bits, but that 32nd bit is giving me fits. To do it with math, you've got to know a bit about IEEE-754 floating point storage (which virtually ALL languages use these days because it's handled by the floating point processor of virtually all CPUs). Wikipedia has a pretty good page on it http://en.wikipedia.org/wiki/Single-...g-point_format. The problem comes in with the NaN's (not a number values). Once all the bits in the exponent part of the SINGLE go to "1" (a NaN), the other bits become irretrievable via math, unless I'm just missing something.

    This is a substantial challenge, and maybe it can't be done. I promise there's a good reason I'm trying to do it. Also, if the question gets booted because it's not pure VB6, that's okay too. Just thought I'd throw out the challenge.

    Regards,
    Elroy

    p.s. Just to further clarify, the SINGLE is just used to temporarily "store" the LONG. The bits won't be used while being stored in the single until they are retrieved back into the LONG.
    Last edited by Elroy; Aug 28th, 2014 at 03:21 PM.

  2. #2
    PowerPoster
    Join Date
    Feb 2012
    Location
    West Virginia
    Posts
    14,205

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Good luck To me that would be a waste of time in VB given that there are functions to convert one type to another already.

  3. #3

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Yeah, I've been chatting on another forum with someone smarter than me. And, IMO, that's a bit unusual. She's pretty clear that once a float goes to a NaN, you've lost control of it. You can still test for the sign, but that's it. Therefore, I don't think it can be done and I'm giving it up.

  4. #4
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    There isn't a function to map an integer to floating point number. All the bits in a float are not usable,and the NaN is not a number but has a bit representation. Let's face the problem..We say that we have to put 10/3 in a long.We can't.. We have to multiply by a factor to preserve the accuracy and we have to hold that factor someware. So memory for one long isn't enough for a 10/3 that easy can save in a single type variable. The single also has an accuracy but it comes with the format of the type. So the real problem to map a long to a real or single for the matter of this thread is the difference of formats. Variables are not as numbers, with varying base, but they have a logical background, a bundled algorithm to express the number representation. Each algorithm has own limitations, with no equivalent in strength. Mainly any number as long has the exact accuracy, but any number as single has own accuracy. So only the memory occupated by a long can be readed by a single in a binary file, but maybe we can transform it to a meaningful number.I think that floating point processor raise a fault if NaN founded.

  5. #5

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Yeah, I've played with it in math quite a bit. Once all the bits of the exponent of an IEEE single go to one, we're done for (i.e., a NaN). That means that 1/256 of the possible combinations of the bits of a single are unusable (all the bits of the exponent going to one happens 1/256 times). Therefore, we could say that we can, in theory, get a long into a single (with math) 255/256 (or 99.6%) of the time, but if it's not 100%, it's worthless. The sign bit for zeros is also another problem. There may be a way to detect negative 0 in a single, but I'm not sure what it'd be.

    And bitwise operators won't work on a single, so that's out too. I'm gonna give it up, and chalk it up as "can't be done". Thanks for helping me to come to that conclusion.

  6. #6
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Quote Originally Posted by Elroy View Post
    And bitwise operators won't work on a single, so that's out too. I'm gonna give it up, and chalk it up as "can't be done".
    Still wondering about the "why trying something like that?"-question.

    Was it only for educational purposes - or did you try to solve a real practical problem?
    (from your OP that seemed to be the case, since you wrote: "there's a good reason...")
    Just curious.

    Olaf

  7. #7

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Hey Schmidt,

    I'm actually still working on it, but taking a different approach. It's for a little c-based gaming macro language. Very limited and very sandbox-circumscribed. That's why the no API allowed. Also, each macro is limited to 64k of server memory, so the code has to be very efficient. That's why the conversion. I'll outline the entire problem, for those who are truly interested. Also, one more caveat. The macro language doesn't allow structures (or UDTs in VB6 terms), but it does have some pre-defined structures. However, there are things quite similar to arrays.

    Ok, here's the problem. There are these things called UUIDs. There's a good wikipedia page on them, if you'd like to know more about them. Basically, they're 32 hex digit numbers, something like "08F0A76C89F285CD452313CDFE87FE21". For rather esoteric reasons, each of these requires 102 bytes of macro memory to store. If you're storing many of them, you can rather quickly eat up your 64k limit. Ok, that's sort of part one.

    If you recognize that these UUIDs are just large hex numbers, you also realize that they can be converted to true numbers and stored in four LONGs. So, something like...

    Type MyUDT
    L1 as long
    L2 as long
    L3 as long
    L4 as long
    End Type

    ... could be used to store each of these. And array of these UDTs would do wonderfully. This is certainly a possibility. The UDT isn't possible, but a strided array of LONGs (jumping over every four elements) to reconstruct the UUID values would certainly work. A LONG, in this silly little language (although only 4 bytes) still takes 16 bytes of macro storage per LONG. I guess it's all the address pointers and things. So, that approach would reduce each UUID from 102 bytes each to 16*4=64 bytes each.

    However, one of the pre-defined structures (think UDT) in this little language looks like this...

    Type InternalUdt
    s1 as single
    s2 as single
    s3 as single
    s4 as single
    End Type

    These are actually something called a quaternion. There's also a wikipedia page on these quaternions. They're used for making 3D rotation and orientation changes. Each of these quaternions uses only 28 bytes of macro memory, even though the SINGLEs use only 4 bytes each. These four SINGLEs in this quaternion structure are IEEE-754 compliant, just like VB6 singles. But, if we could use these, it would reduce the storage of each UUID from 102 bytes to 28 bytes.

    So, again recognizing that these quaternions have exactly 16 bytes of storage space available in them, in theory, they're ideal for packing one of these UUIDs into it to maximize storage efficiency. However, every single bit must be used if they are to truly accommodate the 32 digit UUID characters.

    At this point, you're probably sorry you asked, but there it is. *laughs* We have a bit of a challenge going to see who can do it. But squeezing every bit out of a SINGLE to use for storage is a bit of a problem. Again, it goes back to those darned NaN values (see IEEE-754 specifications). Also the sign bit when it's zero is also another problem we haven't totally solved.

    It's basically the same problem irrespective of the language, so I thought I'd ask in this forum.

    Take care.
    Last edited by Elroy; Aug 29th, 2014 at 07:03 PM.

  8. #8
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    It would seem you would have to come up with some kind of compression scheme, since you can't use all combination of 32 bits in a Single (aka float) value.
    But until you come up with a compression scheme, you could use one quaternion (28 bytes) and a Long (16 bytes) to hold the UUID in 44 bytes of allocated memory by storing 3 bytes of a UUID long in one of the quaternion floats (extremely easy to do), and the fourth byte in one of the bytes of the Long.

  9. #9

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Transfer LONG to SINGLE (and vice versa) with pure math.

    Very good, passel. That is EXACTLY what I did. I just forgot about the 8 bits of the exponent of a single, and stuffed those bits (times 4) into a LONG. So I've got pairs of quaternions and longs that represent my UUIDs. I just finished it up this afternoon. ) I'd post the code here, but I'm afraid of being yelled at for posting C code on a VB6 forum. Actually, they can't get too terribly mad at me for just posting a PasteBin link. So here it is for those truly interested: http://pastebin.com/d3tmDHSH
    Last edited by Elroy; Aug 29th, 2014 at 08:43 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width