ts-7000
[Top] [All Lists]

[ts-7000] Crazy casting issue double <-> int_64_t (long long)

To:
Subject: [ts-7000] Crazy casting issue double <-> int_64_t (long long)
From: "itguysam" <>
Date: Thu, 07 Jan 2010 22:27:13 -0000
Hey guys I have found an interesting bug with the cross compiler from 
Technologics. If you cast between double/"long long" (in either direction) it 
produces crazy results. If I had to guess I would say that it was just doing a 
"reinterpret cast" and not actually modifying the data at all. I have a simple 
test case that shows the behavior but I need help testing it with recent 
versions of the cross compiler so I can know if this is an issue that has 
already been addressed by the compiler folks.  What I really need is this test 
case compiled and run on ts boards so we can see if this occurs on all the 
technologic devices/ all the cross compiler versions/ maybe the kernel version. 
Also optimization levels appear to affect how the bug manifests, with -03 it 
appears it uses the last value that it was compared against.

I can tell you that this bug crops up with the following configuration:
compiler: gcc-3.3.4-glibc-2.3.2 
uname: Linux proto2 2.4.26-ts11 #22 Tue Jun 6 12:23:09 MST 2006 
device: ts-7250

Output:
$ ./arm.exe
Failure: double->int_64_t doesn't cast correctly: 0 != 1003
Failure: int_64_t->double doesn't cast correctly: 1002 != 1004
Failure: int_64_t->double doesn't cast correctly: 1e-05 != 1006
Failure: int_64_t->double doesn't cast correctly: 1011 != 4.29497e+09
Failure: double->int_64_t doesn't cast correctly: 0 != 4294967296


--------------------------- CastingTest.cpp -------------------------
#include <sstream>
#include <iostream>

template <typename T1, typename T2>
T2 TestCast(T1 input){
        return static_cast<T2>(input);
}

template <typename T1>
bool IsEqual(T1 a, T1 b){
        return a == b;
}

template <>
bool IsEqual(double a, double b){
        double diff = a - b;
        if(diff < 0) diff = -diff;
        return diff <= 1e-5;
}

template <>
bool IsEqual(float a, float b){
        float diff = a - b;
        if(diff < 0) diff = -diff;
        return diff <= 1e-5;
}

#define CHECK_CAST(t1, t2, a, b)\
        {t2 amod = TestCast<t1, t2>(a);\
        if(!IsEqual<t2>(amod,(b))){\
                        std::ostringstream oss;                                 
\
                        oss << (#t1)<< "->" << (#t2) << " doesn't cast 
correctly: " << (amod) << " != " << (b); \
                        std::cout << "Failure: " << oss.str() << std::endl;\
        }}

typedef long long int_64_t;

int main(int argc, char* argv[])
{
        CHECK_CAST(double,int,1000.0,1000);
        CHECK_CAST(double,float,1001.0,1001.0f);
        CHECK_CAST(double,long,1002.0,1002);

        CHECK_CAST(double,int_64_t,1003.0,1003);

        CHECK_CAST(int_64_t,double,1004,1004.0);

        CHECK_CAST(double,float,1012.0,1012.0f);
        CHECK_CAST(int_64_t,double,1006,1006.0);

        CHECK_CAST(int,double,1007,1007.0);
        CHECK_CAST(long,double,1008,1008.0);
        CHECK_CAST(int,float,1009,1009.0f);

        CHECK_CAST(float,int_64_t,1010.0f,1010);
        CHECK_CAST(float,int,1011.0f,1011);

        CHECK_CAST(int_64_t,double,4294967296LL,4294967296.0);
        CHECK_CAST(double,int_64_t,4294967296.0,4294967296LL);
        return 0;
}

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

/*
Also : A good work around would also be appreciated, the one I am using is far 
from optimal:
*/
double SafeCastInt64ToDouble(int_64_t aInput){
#ifdef ARM
                long upper =  (aInput & 0xFFFFFFFF00000000LL) >> 32;
                unsigned long lower = (aInput & 0x00000000FFFFFFFFLL);

                //Shift the upper portion back into the correct range ( e1<<e2 
becomes e1 * pow(2.0, e2), in our case pow(2,32)=4294967296)
                double f1 = upper * 4294967296.0; 
                double f2 = lower;
                double dblVar = f1 + f2;

                return dblVar;
#else
                return static_cast<double>(aInput);
#endif
        }



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

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

<Prev in Thread] Current Thread [Next in Thread>
  • [ts-7000] Crazy casting issue double <-> int_64_t (long long), itguysam <=
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU