Double conversion



  • Hi!

    I'm having a small trouble sending double data type via USB. I have a double data type but and i want to send it like a char format (8 bits), i was thinking to mask the number and make a bit shifting:

    double x = 0.9865236;
    char SendBuffer[64];

    SendBuffer[0] = x & 0xFF; // Higher part of the number
    SendBuffer[1] = x >> 8; // Low part of the number

    But obviously is not possible to convert like this... but i don't know how to do it in a correct way...

    Any suggestion??

    Thanks!


  • Moderators

    @
    QByteArray toSend(QByteArray::number(x));
    char *data = toSend.data();
    @

    That does not take endianess into account, so for better results you should probably aim for QDataStream or QTextStream. Or send it with XML if you prefer.



  • Hi sierdzio,

    The data are going to be send to a microcontroller, with that method i send each character separately, expending 8 bit for each one. As i will use 16 bits data length, my idea was to send it with only two bytes to fit to my project restrictions.

    Anyway thank you so much because i didn't know that method, and for sure i will use it in the future.



  • I am not sure I understand 100% what you are trying to do. You want to send a double (64 bits/ 8 bytes) to a microcontroller as 16 bits (2 bytes)? What should happen to the rest of the data in the double, or am I misunderstanding something?

    Say you want to send the double (8 bytes) as 8 characters, I use the following code (bit modified since I use templates to handle all data types).

    @
    double valueToSend = 0.9865236;
    char tempBuffer[sizeof(double)];
    memcpy(&tempBuffer, &valueToSend, sizeof(double));
    /* Probably handle endianess, I send in reverse order:
    first send index 7, then 6 until 0
    */
    @

    and then on the other side to build the double again:
    @
    char receivedBytes[sizeof(double)];
    char tempBuffer[sizeof(double)];
    /* Handle endianness, depends on your system, if you send in reverse do the following: /
    for(int idx = 0; idx < sizeof(double); ++idx) {
    tempBuffer[idx] = receivedBytes[sizeof(double) - 1 - idx];
    }
    /
    If you did not send in reverse order, you can just use receivedBytes directly in the memcpy below */
    double valueReceived;
    memcpy(&valueReceived, &tempBuffer, sizeof(double));
    @

    Note: I always gets confused about endianess :P

    [quote author="sierdzio" date="1412009097"] you should probably aim for QDataStream or QTextStream[/quote]

    But I think QDataStream might be a better solution as sierdzio mentioned, I would suspect it would work correctly (the code above is about 4 years old, I did not know QDataStream at that time, and my receiver was not under my control).



  • Ok I will explain better, basically I have a decimal number which actually i declared as double type, and I want to send it via USB with a 16 bits short or 8 bits char buffer type truncating or losing the precision required for the conversion, because I will only use 16 bit resolution on the microcontroller.

    So the target is to convert the decimal number into a 2 bytes number to make the reading it easier as possible for the microcontroller.

    When i do the oposite operation, i receive the data sampled with an ADC from the microcontroller trought the USB into a short int buffer, the Qt app can "understand" it as a decimal, declaring as short int in the PC and as short in the micro. This is something that i can't really understand because i thought that short is a signed integer type...

    Thanks!



  • Then the problem is not really Qt related. You need to do some magic to get the data to fit in 16 bits.

    1. You can round the value by assigning it to an int, and then make sure the values is smaller than 2^16 (65 536) and take high and low part as in your original question, but that might not be good enough, especially if you need precision.
    2. You can encode the 16 bits in some way, to say 1 bit in the 16 bits each represent some increment, like 0.1 (I can give you more information if this is what you want to do).

    How does the microcontroller use the value?



  • Yes exactly, the problem is to take the double 64bits number (or another type with less bits, 16 would be perfect) and take only the 16 most significant to send them to the microcontroller.

    My trouble is the cast between the double to binary.



  • [quote author="Badger" date="1412069758"]
    How does the microcontroller use the value?
    [/quote]

    Casting double to binary and getting most significant bits will not work, look at the "IEEE double format":https://en.wikipedia.org/wiki/Double-precision_floating-point_format (the way it is managed in the app). You need follow steps to get the value smaller as described in step 1 of my above post.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.