RoboPro .rpp float calculation
Forumsregeln
Bitte beachte die Forumsregeln!
Bitte beachte die Forumsregeln!
RoboPro .rpp float calculation
RoboPro stores a 48 bit float in the XML .rpp file as datatype=11.
and is using 3 values for this: value0, value1 and value2.
For example:
-285 is stored as value0= -24567 value1= -29056 value2= 0
285 is stored as value0= 8201 value1= -29056 value2= 0
0 is stored as value0= 2 value1= 0 value2= 0
-360 is stored as value0= -24567 value1= -19456 value2= 0
410 is stored as value0= 8201 value1= -13056 value2= 0
360 is stored as value0= 8201 value1= -19456 value2= 0
Can somebody clarified how this calculation (function f) is done in general?
result 48 bits float =f(value0, value1, value2)
and is using 3 values for this: value0, value1 and value2.
For example:
-285 is stored as value0= -24567 value1= -29056 value2= 0
285 is stored as value0= 8201 value1= -29056 value2= 0
0 is stored as value0= 2 value1= 0 value2= 0
-360 is stored as value0= -24567 value1= -19456 value2= 0
410 is stored as value0= 8201 value1= -13056 value2= 0
360 is stored as value0= 8201 value1= -19456 value2= 0
Can somebody clarified how this calculation (function f) is done in general?
result 48 bits float =f(value0, value1, value2)
Re: RoboPro .rpp float calculation
From RoboPro help:
The precision of arithmetic operations is 48 bits with a 32 bit mantissa. This corresponds to a precision of slightly more than 9 decimal digits.
But how to come from the value), value1, value2 to a C# or C/C++ Double type?
Has there been used the old Pascal 48-bits real type?
https://stackoverflow.com/questions/319 ... nt-integer
http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
No, this has a 40 bits mantissa.
The precision of arithmetic operations is 48 bits with a 32 bit mantissa. This corresponds to a precision of slightly more than 9 decimal digits.
But how to come from the value), value1, value2 to a C# or C/C++ Double type?
Has there been used the old Pascal 48-bits real type?
https://stackoverflow.com/questions/319 ... nt-integer
http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
No, this has a 40 bits mantissa.
- MasterOfGizmo
- Beiträge: 2720
- Registriert: 30 Nov 2014, 07:44
Re: RoboPro .rpp float calculation
The MSB of value 0 ist the sign, the rest of value 0 is the exponent and value 1 and value 2 are the mantissa.
Arduino für fischertechnik: ftDuino http://ftduino.de, ftDuino32 http://ftduino.de/32
- MasterOfGizmo
- Beiträge: 2720
- Registriert: 30 Nov 2014, 07:44
Re: RoboPro .rpp float calculation
value1 is -29056. This is unsigned 36480. Append value 2 which is 0 (shift 16 bits left and add value 2) gives 2390753280. Divide by 2^32 gives 0,556640625. Sign is -1 since value 0 (-24567) is negative.value0= -24567 value1= -29056 value2= 0
Thus the mantissa is -0.556640625
Value 0 without sign is 8201. Subtract the exponent offset which seems to be 2^13 = 8192. The exponent thus is 8201 - 8192 = 9.
The result thus is -0.556640625 * 2^9 = -0.556640625 * 512 = -285
So value0= -24567 value1= -29056 value2= 0 is -285
Arduino für fischertechnik: ftDuino http://ftduino.de, ftDuino32 http://ftduino.de/32
Re: RoboPro .rpp float calculation
Thanks MasterOfGizmo, I will try it.
There were a lot of possibilities for the float-format.
http://www.quadibloc.com/comp/cp0201.htm
https://stackoverflow.com/questions/319 ... nt-integer
https://community.arm.com/developer/too ... conversion
There were a lot of possibilities for the float-format.
http://www.quadibloc.com/comp/cp0201.htm
https://stackoverflow.com/questions/319 ... nt-integer
https://community.arm.com/developer/too ... conversion
Zuletzt geändert von vleeuwen am 03 Okt 2019, 09:42, insgesamt 2-mal geändert.
Re: RoboPro .rpp float calculation
The result in C#.
Reverse engineering of data type 11 in the RoboPro .rpp XML serialization.
Based on: http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
Supporting methode:
Reverse engineering of data type 11 in the RoboPro .rpp XML serialization.
Based on: http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
Code: Alles auswählen
public Double Convert(string val0, string val1, string val2)
{
Double result = Double.NaN;
try
{
byte[] real48 = null;
Int16 i0 = Int16.Parse(val0), i1 = Int16.Parse(val1), i2 = Int16.Parse(val2);
byte[] bi0 = BitConverter.GetBytes(i0), bi1 = BitConverter.GetBytes(i1), bi2 = BitConverter.GetBytes(i2);
real48 = addByteToArray(bi0, bi1, bi2);
//=======================================================
Int32 exponent = ((real48[5] & 0x7F) * 0x100) + real48[4];// first 15 bits
exponent = exponent - 8192; //8192= Math.Pow(2.0, 13) but has a double type;
// Now Calculate the mantissa
Double mantissa = 0.0, value = 1.0;
// For Each Byte.
for (int i = 3; i >= 0; i--)
{
int startbit = 7;
//For Each Bit
for (int j = startbit; j >= 0; j--)
{
value = value / 2;// Each bit is worth half the next bit but we're going backwards.
if (((real48[i] >> j) & 1) == 1) mantissa += value; // add the value if bit set.
}
}
if (mantissa == 1.0 && real48[0] == 0) result = 0.0f;// Test for null value
else
{
if ((real48[5] & 0x80) == 0x80) // Sign 16th bit of value0 (byte 4and 5) check
mantissa = -mantissa;
result = mantissa * Math.Pow(2.0, exponent);
}
}
catch (Exception e)
{
throw new System.Exception("Conversion error", e.InnerException);
}
return result;
}
Code: Alles auswählen
public byte[] addByteToArray(byte[] b0Array, byte[] b1Array, byte[] b2Array)
{
byte[] concat = null;
if (b2Array.Length == 2 && b1Array.Length == 2 && b0Array.Length == 2)
{
concat = new byte[6];
System.Buffer.BlockCopy(b2Array, 0, concat, 0, 2);
System.Buffer.BlockCopy(b1Array, 0, concat, 2, 2);
System.Buffer.BlockCopy(b0Array, 0, concat, 4, 2);
}
else
{ throw new System.ArgumentException("One of the parameter is not a 2 bytes value", "conversion error"); }
return concat;
}
Zuletzt geändert von vleeuwen am 03 Okt 2019, 09:44, insgesamt 4-mal geändert.
- MasterOfGizmo
- Beiträge: 2720
- Registriert: 30 Nov 2014, 07:44
Re: RoboPro .rpp float calculation
Your code will only work on little endians.
Arduino für fischertechnik: ftDuino http://ftduino.de, ftDuino32 http://ftduino.de/32
Re: RoboPro .rpp float calculation
I know, but the organisation in the byte array can be adapted to the actual situation.
However for .NET framework and the RoboPro serialization this gives the right result.
For the reader who are not familiair with the meaning of "endians", see for example:
https://en.wikipedia.org/wiki/Endianness
Endianness refers to the order of bytes (or sometimes bits) within a binary representation of a number in hardware as well in software.
However for .NET framework and the RoboPro serialization this gives the right result.
For the reader who are not familiair with the meaning of "endians", see for example:
https://en.wikipedia.org/wiki/Endianness
Endianness refers to the order of bytes (or sometimes bits) within a binary representation of a number in hardware as well in software.
- MasterOfGizmo
- Beiträge: 2720
- Registriert: 30 Nov 2014, 07:44
Re: RoboPro .rpp float calculation
As I showed above it's easy to convert directly without mapping the data to byte arrays first. This would make the code much simpler and it would run on any target without modifications.
Something like:
Something like:
Code: Alles auswählen
double mantissa = (((uint32_t)((uint16_t)value1)<<16) + ((uint16_t)value2)) / pow(2,32);
if(value0 < 0) mantissa = -mantissa;
int exponent = (value0 & 0x7fff)-8192;
double result = mantissa * pow(2,exponent);
Arduino für fischertechnik: ftDuino http://ftduino.de, ftDuino32 http://ftduino.de/32
- MasterOfGizmo
- Beiträge: 2720
- Registriert: 30 Nov 2014, 07:44
Re: RoboPro .rpp float calculation
or if your prefer a simple one liner:
Code: Alles auswählen
double result = ((value0<0)?-1.0:1.0)*(((uint32_t)((uint16_t)value1)<<16) + ((uint16_t)value2)) / pow(2,8224-(value0 & 0x7fff));
Arduino für fischertechnik: ftDuino http://ftduino.de, ftDuino32 http://ftduino.de/32
Re: RoboPro .rpp float calculation
Certainly there are a lots of possibilities, no doubt about that.
I choose for this solution because it shows all the steps in C# and it has been based on this example: http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
One-liner code, the program language APL is famous for that, is less easy to understand and to modify later.
The compiler will do the optimization of the code.
The functional specification is the more important part
I choose for this solution because it shows all the steps in C# and it has been based on this example: http://www.shikadi.net/moddingwiki/Turbo_Pascal_Real
One-liner code, the program language APL is famous for that, is less easy to understand and to modify later.
The compiler will do the optimization of the code.
The functional specification is the more important part
Code: Alles auswählen
/// <summary>
/// Converts a RoboPro dataType 11, as use in the .rpp serialization file, into a Double
/// </summary>
/// <param name="val0">string with a 2 bytes number, serialized as a signed integer </param>
/// <param name="val1">string with a 2 bytes number, serialized as a signed integer</param>
/// <param name="val2">string with a 2 bytes number, serialized as a signed integer</param>
/// <returns> The value</returns>
public static Double Convert(string val0, string val1, string val2)