[Tinyos-help] Floating Point Arithmetic and FTSP -- A solution
Sinan Yildirim
sinanyil81 at gmail.com
Wed Nov 24 05:55:00 PST 2010
Hi all,
I have recently noticed that the floating point division operation for
calculating the slope of the linear regression line in TimeSyncP.nc file of
FTSP protocol in TinyOS has some problems. If we take a look at the
following nesC code of FTSP, we can see that localSum and offsetSum
variables are* int64_t*. However, division of these two 64 bit numbers by
casting to the float is problematic.
for(i = 0; i < MAX_ENTRIES; ++i)
if( table[i].state == ENTRY_FULL ) {
int32_t a = table[i].localTime - newLocalAverage;
int32_t b = table[i].timeOffset - newOffsetAverage;
localSum += (int64_t)a * a;
offsetSum += (int64_t)a * b;
}
if( localSum != 0 )
*newSkew = (float)offsetSum / (float)localSum;*
atomic
{
skew = newSkew;
offsetAverage = newOffsetAverage;
localAverage = newLocalAverage;
numEntries = tableEntries;
}
The main issue is, in *Micaz* platform floating point numbers are *32 bit
numbers*! (And may be in most other platforms). And if we cast an int64_t to
float, we will get garbage data (especially when the casted variables are
negative).
Consider the following localtime-globaltime pairs. These are the values I
have recorded when running Ftsp between 2 nodes (1 root and 1 slave). The
following 8 entries are the pairs which the slave node used to fill its
regression table. If you run the linear regression code with the current
code of FTSP in the tinyos 2.1.1 you wont get *0x4d457df *value* *when the
local time of the slave node is *0x4c61357*.
[local=0x7b28be] [global=0x896e7b]
[local=0x1048612] [global=0x112cba8]
[local=0x18de365] [global=0x19c28d5]
[local=0x21740b9] [global=0x2258602]
[local=0x2a09e0c] [global=0x2aee32e]
[local=0x329fb5f] [global=0x338405b]
[local=0x3b358b2] [global=0x3c19d87]
[local=0x43cb605] [global=0x44afab3]
*[local=0x4c61357] [global=0x4d457df]*
My suggestion is adding a *getSlope* function as follows:
float getSlope(int64_t a,int64_t b){
bool negative = FALSE;
float s = 0.0;
if(a<0){ // get the original positive number
negative = TRUE;
a--;
a =~a;
}
if(b<0){
if(negative==FALSE){
negative = TRUE;
}
else{
negative = FALSE;
}
b--;
b =~b;
}
while(((a>>32)&0xFFFFFFFF) || ((b>>32)&0xFFFFFFFF)){
a>>=4;
b>>=4;
}
s = (float)a/(float)b;
if(negative == TRUE){
s*=-1.0;
}
return s;
}
This function converts int64_t variables to int32_t and then calculates the
slope. Then we can change TimeSyncP.nc as:
for(i = 0; i < MAX_ENTRIES; ++i)
if( table[i].state == ENTRY_FULL ) {
int32_t a = table[i].localTime - newLocalAverage;
int32_t b = table[i].timeOffset - newOffsetAverage;
localSum += (int64_t)a * a;
offsetSum += (int64_t)a * b;
}
if( localSum != 0 )
*newSkew = getSlope(offsetSum,localSum);*
atomic
{
skew = newSkew;
offsetAverage = newOffsetAverage;
localAverage = newLocalAverage;
numEntries = tableEntries;
}
Any other suggestions or ideas??
Sinan
Ege University
Computer Engineering Department
Izmir, TURKEY
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://www.millennium.berkeley.edu/pipermail/tinyos-help/attachments/20101124/571ce6c9/attachment.htm
More information about the Tinyos-help
mailing list