How can I use quad precision math in a Qt project?



  • After reading this https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html I tried to add -mfloat128 argument to GCC but the project did not compile as that option was not supported under my 4.8.5
    Turned out that the article on GCC site was wrong and the argument should have been -lquadmath. Then the project compiled, but failed to link:

    cd '/usr/home/leo/NetBeansProjects/QtApplication_1'
    /usr/local/bin/gmake -f Makefile CONF=Debug QMAKE=/usr/local/lib/qt5/bin/qmake
    "/usr/local/bin/gmake" -f nbproject/Makefile-Debug.mk QMAKE=/usr/local/lib/qt5/bin/qmake SUBPROJECTS= .build-conf
    gmake[1]: Entering directory '/usr/home/leo/NetBeansProjects/QtApplication_1'
    /usr/local/lib/qt5/bin/qmake VPATH=. -o qttmp-Debug.mk nbproject/qt-Debug.pro
    mv -f qttmp-Debug.mk nbproject/qt-Debug.mk
    "/usr/local/bin/gmake" -f nbproject/qt-Debug.mk dist/Debug/GNU-Generic/QtApplication_1
    gmake[2]: Entering directory '/usr/home/leo/NetBeansProjects/QtApplication_1'
    /usr/local/lib/qt5/bin/uic newForm.ui -o ui_newForm.h
    g++ -c -pipe -O3 -lquadmath -g -std=c++11 -Wall -W -pthread -D_THREAD_SAFE -fPIC -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -Inbproject -I. -I../../../../local/include/qt5/QtConcurrent -I../../../../local/include/qt5 -I../../../../local/include/qt5/QtWidgets -I../../../../local/include/qt5/QtGui -I../../../../local/include/qt5/QtCore -I. -I../../../../local/include -I. -I../../../../local/include -I../../../../local/lib/qt5/mkspecs/freebsd-clang -o build/Debug/GNU-Generic/main.o main.cpp
    g++ -c -pipe -O3 -lquadmath -g -std=c++11 -Wall -W -pthread -D_THREAD_SAFE -fPIC -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -Inbproject -I. -I../../../../local/include/qt5/QtConcurrent -I../../../../local/include/qt5 -I../../../../local/include/qt5/QtWidgets -I../../../../local/include/qt5/QtGui -I../../../../local/include/qt5/QtCore -I. -I../../../../local/include -I. -I../../../../local/include -I../../../../local/lib/qt5/mkspecs/freebsd-clang -o build/Debug/GNU-Generic/newForm.cpp.o newForm.cpp.cc
    newForm.cpp.cc:191:6: warning: unused parameter 'pA' [-Wunused-parameter]
     void newForm::handleRubberBandChanged(QRect r, QPointF pA, QPointF pB){
          ^
    newForm.cpp.cc:191:6: warning: unused parameter 'pB' [-Wunused-parameter]
    /usr/local/lib/qt5/bin/moc -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -I/usr/local/lib/qt5/mkspecs/freebsd-clang -I/usr/home/leo/NetBeansProjects/QtApplication_1/nbproject -I/usr/local/include/qt5/QtConcurrent -I/usr/local/include/qt5 -I/usr/local/include/qt5/QtWidgets -I/usr/local/include/qt5/QtGui -I/usr/local/include/qt5/QtCore -I. -I/usr/include/c++/v1 -I/usr/include/clang/3.4.1 -I/usr/include newForm.h -o moc_newForm.cpp
    g++ -c -pipe -O3 -lquadmath -g -std=c++11 -Wall -W -pthread -D_THREAD_SAFE -fPIC -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -Inbproject -I. -I../../../../local/include/qt5/QtConcurrent -I../../../../local/include/qt5 -I../../../../local/include/qt5/QtWidgets -I../../../../local/include/qt5/QtGui -I../../../../local/include/qt5/QtCore -I. -I../../../../local/include -I. -I../../../../local/include -I../../../../local/lib/qt5/mkspecs/freebsd-clang -o build/Debug/GNU-Generic/moc_newForm.o moc_newForm.cpp
    clang++ -pthread -Wl,-rpath,/usr/local/lib -o dist/Debug/GNU-Generic/QtApplication_1 build/Debug/GNU-Generic/main.o build/Debug/GNU-Generic/newForm.cpp.o build/Debug/GNU-Generic/moc_newForm.o   -L/usr/local/lib -lQt5Widgets -lQt5Gui -lQt5Concurrent -lQt5Core -lGL 
    /usr/bin/ld: Dwarf Error: found dwarf version '4', this reader only handles version 2 information.
    build/Debug/GNU-Generic/newForm.cpp.o: In function `_ZN12QtConcurrent9MapKernelIPiZN7newForm18handleBtnCalculateEvEUlRiE_E12runIterationES1_iPv':
    newForm.cpp.cc:(.text+0x157): undefined reference to `__extenddftf2'
    newForm.cpp.cc:(.text+0x175): undefined reference to `__extenddftf2'
    newForm.cpp.cc:(.text+0x1a9): undefined reference to `__gttf2'
    newForm.cpp.cc:(.text+0x1c5): undefined reference to `__gttf2'
    newForm.cpp.cc:(.text+0x1e7): undefined reference to `__multf3'
    newForm.cpp.cc:(.text+0x202): undefined reference to `__multf3'
    newForm.cpp.cc:(.text+0x211): undefined reference to `__subtf3'
    newForm.cpp.cc:(.text+0x220): undefined reference to `__addtf3'
    newForm.cpp.cc:(.text+0x239): undefined reference to `__addtf3'
    newForm.cpp.cc:(.text+0x247): undefined reference to `__multf3'
    newForm.cpp.cc:(.text+0x256): undefined reference to `__addtf3'
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    nbproject/qt-Debug.mk:224: recipe for target 'dist/Debug/GNU-Generic/QtApplication_1' failed
    gmake[2]: *** [dist/Debug/GNU-Generic/QtApplication_1] Error 1
    gmake[2]: Leaving directory '/usr/home/leo/NetBeansProjects/QtApplication_1'
    nbproject/Makefile-Debug.mk:65: recipe for target '.build-conf' failed
    gmake[1]: *** [.build-conf] Error 2
    gmake[1]: Leaving directory '/usr/home/leo/NetBeansProjects/QtApplication_1'
    nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
    gmake: *** [.build-impl] Error 2
    

    How can I use quad precision math in a Qt project?
    When I look at the toolchain in Netbeans options there is no mention of clang, only gcc and g++.


  • Moderators

    g++ -c -pipe -O3 -lquadmath -g -std=c++11 -Wall -W -pthread -D_THREAD_SAFE -fPIC -DQT_WIDGETS_LIB -DQT_GUI_LIB 
    clang++ -pthread -Wl,-rpath,/usr/local/lib -o dist/Debug/GNU-Generic/QtApplication_1 build/Debug/GNU-Generic/main.o build/Debug/GNU-Generic/newForm.cpp.o build/Debug/GNU-Generic/moc_newForm.o   -L/usr/local/lib -lQt5Widgets -lQt5Gui -lQt5Concurrent -lQt5Core -lGL 
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    

    that's strange! Somehow it looks like you're mixing different compilers!
    Did you check the Kit you use to build the project?

    newForm.cpp.cc:(.text+0x211): undefined reference to `__subtf3'
    

    that means that you have to link against a library. Try to find out which one via:

    ldd /path_to_/libquadmath.so
    

  • Qt Champions 2016

    To add to @jsulm you don't appear to link neither against the standard math library nor quadmath. Additionally, __extenddftf2 and the like are floating point emulation routines provided from g++ for devices without native support, why would you want them in the first place? On that same page why do you need extended floating point support? I had the need to use it only once in my entire life and for a problem where I had a badly behaved van der Waals force.

    PS.
    The calculations with the standard double type are by design done in an extended floating point register, so there's rarely a good reason to need more than the language provides.



  • My biggest problem is that I am piecing together a project from:

    • Netbeans, where tool chain specified gcc and g++ and had no mention of clangwhatsoever;
    • Misleading info on GCC web site that stated I had to use -mfloat128;
    • and whatever tips I can find by googling;

    so no, I am not sure I am doing it right. I do not need emulation routines.
    The project was not compiling until I removed -mfloat128 and added -lquadmath to CXX options. What's next I have no idea, this seems to be a very poorly documented feature.

    Perhaps Netbeans generates its own makefiles where it uses clang in place of gcc, I will have to look into that. Oracle does not support Netbeans and its developers do not answer any questions, so I am hung out to dry.


  • Qt Champions 2016

    @nulluse
    Well, I suggest first trying to find out what the problem with that clang is, why it's appearing at all, and then if the problems persists, we could try to help. For now this'd be my best "suggestion".



  • This appears to be caused by a bug in FreeBSD port of Qt5.
    Its qmake-qt5 created qt-Debug.mk file that had clang in place of g++ for a linker:

    LINK          = clang++
    LFLAGS        = -pthread -Wl,-rpath,/usr/local/lib
    

    I tried compiling under Fedora linux and it built just fine using g++ all the way.

    As to why I need quad precision math - it is due to the requirement to support very small numbers that round to 0 when double or long double is used. Especially while long double optimizes into the FP instructions instead of MMX/SSE.


  • Qt Champions 2016

    @nulluse

    As to why I need quad precision math - it is due to the requirement to support very small numbers that round to 0 when double or long double is used.

    They must be really small, as double's dynamic range spans approximately between 10^308 and 10^-308. You might have a catastrophic cancellation problem somewhere in the code and this'd be a reason for the described behavior.

    PS.

    Especially while long double optimizes into the FP instructions instead of MMX/SSE.

    I don't see how the streaming extension would help here. Perhaps you could share a few details on what you're trying to achieve?



  • Are you referring to loss of precision as to catastrophic cancellation?
    And what behaviour does it explain? I do not believe I described any program behaviours here, and rightly so as it has yet to be compiled.


  • Qt Champions 2016

    @nulluse said:

    Are you referring to loss of precision as to catastrophic cancellation?

    Yes, and no. Every floating point operation carries error. Once from rounding, and once from truncation, that's why FP operations are performed in registers larger than the actual type. (e.g. operations with double will be carried in 128bit registers or at least in 80bit ones, so to mitigate those two types of errors.). Additionally, floating point types are kept in normalized form.

    Catastrophic cancellation is a specific scenario where the relative error of the fp operation is unbound (absolute error is always within one to two epsilons). It happens most commonly when you subtract two numbers and those numbers are close numerically. When the result normalization occurs the exponent is shifted, but because of the limited size of the mantissa a lot of significant digits are simply lost. FP stability is quite an extensive topic, so this is only in broad strokes.

    Further reading: http://steve.hollasch.net/cgindex/coding/ieeefloat.html

    And what behaviour does it explain? I do not believe I described any program behaviours here, and rightly so as it has yet to be compiled.

    I then must have misunderstood the following statement: "As to why I need quad precision math - it is due to the requirement to support very small numbers that round to 0 when double or long double is used.".
    What I reckoned is you're in fact changing an existing program to accommodate that requirement. As this doesn't seem to be the case, I apologize, and if I may insert a suggestion here:
    Use brute force methods (arbitrary/quad precision arithmetic) with some care. They are pretty slow, and don't support most of the functions you have available for float/double (e.g. exponents, logarithms etc.). My advice is to carefully consider the problem and choose a numerically stable algorithm that does the job with preference, instead of extending the precision.

    Kind regards.



  • Yes, we all understand what are the implications of using __float128 and we have to support >30 decimal points for this application. I was not describing a computational problem when I said that 'the numbers rounded to 0'. This was to allude to using the numbers with the significant digits residing way further to the right than the 15th decimal point of the double type.


  • Qt Champions 2016

    @nulluse said:

    Yes, we all understand what are the implications of using __float128 and we have to support >30 decimal points for this application.

    Sadly, in that case the 113 bit mantissa (about 34 significant decimal digits) of __float128 won't give you much leeway,

    I was not describing a computational problem when I said that 'the numbers rounded to 0'. This was to allude to using the numbers with the significant digits residing way further to the right than the 15th decimal point of the double type.

    Fair enough.


Log in to reply
 

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