Double 64 bit conversion to 32 Float with precision losing

There is problem with Double 64 bit conversion to 32 Float with precision losing​. Below two sketches,

Result on IND.I/O D21G ​board returns -0.00, on UNO board 123.00 (this is correct).

Any ideas ?

#include <UC1701.h>
#include <IEEE754tools.h>

static UC1701 lcd;

void setup() {
  // put your setup code here, to run once:
  lcd.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
 byte tab[8];//decimal 123
  tab[0] =B00000000;
  tab[1] =B00000000;
  tab[2] =B00000000;
  tab[3] =B00000000;
  tab[4] =B00000000;
  tab[5] =B11000000;
  tab[6] =B01011110;
  tab[7] =B01000000;
  float f = doublePacked2Float(tab);
  lcd.setCursor(0,0);
  lcd.print(f);
  delay(1000);
 //Result -0.00
}

#include <IEEE754tools.h>
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  byte tab[8];//decimal 123
  tab[0] =B00000000;
  tab[1] =B00000000;
  tab[2] =B00000000;
  tab[3] =B00000000;
  tab[4] =B00000000;
  tab[5] =B11000000;
  tab[6] =B01011110;
  tab[7] =B01000000;
  float f = doublePacked2Float(tab);
  Serial.println(f);
  delay(1000);
  //Result 123.00
}

/*------------------------------------------------------------*/

Next file :

 

 

 

 

Janusz Imiołczyk
Janusz Imiołczyk
7
| 2 1 2
Asked on 10/10/17, 12:53 PM
0
vote
3055 Views

Hi Janusz,

The D21G is 32-bit (4 bytes), and the 'double' data type is 8 bytes, so you can use this simple code based on 'union' to convert from bytes to double. You can cast the double into a float type, as in the last 2 lines, i assume that changes the precision of the number. Does that solve your issue?

SerialUSB.begin(9600);

while (!SerialUSB);

SerialUSB.println();

union double_8bytes {

double d;

byte b[8];

};

double_8bytes our_number;

our_number.b[0] = B00000000;

our_number.b[1] = B00000000;

our_number.b[2] = B00000000;

our_number.b[3] = B00000000;

our_number.b[4] = B00000000;

our_number.b[5] = B11000000;

our_number.b[6] = B01011110;

our_number.b[7] = B01000000;

SerialUSB.println(our_number.d);

float our_float = our_number.d;

SerialUSB.println(our_float);

 

Tom
Tom
5675
| 1 1 3
Answered on 10/11/17, 2:36 AM
0
vote

Hi Janusz, I have tried your example, and it get a decimal number 123.456 so the code seems to work, can you test it too? If you use the below code, you can see the difference in precision between float and double. 123.4560000000 vs 123.4560012817 SerialUSB.begin(9600); while (!SerialUSB); SerialUSB.println(); union double_8bytes { double d; byte b[8]; }; double_8bytes our_number; our_number.b[0] = B01110111; our_number.b[1] = B10111110; our_number.b[2] = B10011111; our_number.b[3] = B00011010; our_number.b[4] = B00101111; our_number.b[5] = B11011101; our_number.b[6] = B01011110; our_number.b[7] = B01000000; SerialUSB.println(our_number.d,10); float our_float = our_number.d; SerialUSB.println(our_float,10);

Tom
on 10/11/17, 11:37 PM

Hi, Tom yes you have right. It's working fine. Thank you very much!

Janusz Imiołczyk
on 10/12/17, 8:33 AM

Hi Tom,

your code will work only with numbers with out fraction, try below 123.456. I receive 8 bytes (Modbus register 4x16bit unsigned int)

I need code which will transfer Doble 64bit to Float 32bit as it should do IEEE754tools library.On UNO boards it works fine and on DG21G it returns 0.00 or -0.00.

SerialUSB.begin(9600);

while (!SerialUSB);

SerialUSB.println();

union double_8bytes {

double d;

byte b[8];

};

double_8bytes our_number;

 our_number.b[0] = B01110111;
  our_number.b[1] = B10111110;
  our_number.b[2] = B10011111;
  our_number.b[3] = B00011010;
  our_number.b[4] = B00101111;
  our_number.b[5] = B11011101;
  our_number.b[6] = B01011110;
  our_number.b[7] = B01000000;

//Decimal: 123.456

SerialUSB.println(our_number.d);

float our_float = our_number.d;

SerialUSB.println(our_float);

------------------------------------------------------------------------------------------------------------------------------------

SECOND EXAMPLE:

this is code which is tested on UNO and Industrino D21G board with results:

 

//Industrino D21G output :

40 5E DD 2F 1A 9F BE 77 --> -3.482
123.456 --> 20 76 E9 79 E0 0 0 0  --> 0.000

//Uno board output ( change SerialUSB to Serial in code):

40 5E DD 2F 1A 9F BE 77 --> 123.456
123.456 --> 40 5E DD 2F 37 88 3D FE  --> 123.456

Why the same code returns different results on UNO and D21G ?

#include <IEEE754tools.h>
void setup() {
  // put your setup code here, to run once:
  SerialUSB.begin(9600);
  while(!SerialUSB){}
   byte tab[8];
  //FLOAT: 123.456
  //HEX: 40 5E DD 2F 1A 9F BE 77
 /* tab[0] =B01110111;
  tab[1] =B10111110;
  tab[2] =B10011111;
  tab[3] =B00011010;
  tab[4] =B00101111;
  tab[5] =B11011101;
  tab[6] =B01011110;
  tab[7] =B01000000;*/
 
  tab[0] =0x77;
  tab[1] =0xBE;
  tab[2] =0x9F;
  tab[3] =0x1A;
  tab[4] =0x2F;
  tab[5] =0xDD;
  tab[6] =0x5E;
  tab[7] =0x40;

  for (int j=7; j>=0; j--){
    SerialUSB.print(tab[j],HEX);
    SerialUSB.print(' ');
  }
  SerialUSB.print("--> ");
  SerialUSB.print(doublePacked2Float(tab),3);
  SerialUSB.println();
 
  byte fab[8];
  SerialUSB.print("123.456 --> ");
  float2DoublePacked(123.456, fab); 
  for (int i=7; i>=0; i--){
    SerialUSB.print(fab[i],HEX);
    SerialUSB.print(' ');
  }
  SerialUSB.print(" --> ");
  SerialUSB.print(doublePacked2Float(fab),3);
  SerialUSB.println();
  SerialUSB.println();
  delay(5000);
}

void loop() {
  // put your main code here, to run repeatedly:
 
}

 

 

 

 

 

 

 

 

Janusz Imiołczyk
Janusz Imiołczyk
7
| 2 1 2
Answered on 10/11/17, 9:33 AM
0
vote

Your answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

Ask a Question

Keep Informed

About This Forum

This community is for professionals and enthusiasts of our products and services.

Read Guidelines

Question tools

40 follower(s)

Stats

Asked: 10/10/17, 12:53 PM
Seen: 3055 times
Last updated: 10/12/17, 7:20 AM