Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problematic output of fmod (long double, long double)

23 views
Skip to first unread message

Alex Vinokur

unread,
Feb 11, 2016, 4:12:28 AM2/11/16
to
It seems that output of fmod (long double, long double) in this test is problematocs.
Any suggestions?

See below.


> g++ --version
g++ (GCC) 4.9.2

> uname -srvmpio
CYGWIN_NT-6.1 1.7.34(0.285/5/3) 2015-02-04 12:12 i686 unknown unknown Cygwin


> g++ test1.cpp
// No errors, no warnings


> ./a.exe

l1 = 4294967296
l2 = 72057594037927934
l3 = 4294967294

d1 = 4294967296
d2 = 72057594037927934
d3 = 0 // Expected 4294967294


// -------- Program test1. cpp --------
#include <iostream>
#include <iomanip>
#include <cmath>

int main (int argc, char** argv)
{

long long l1 = 4294967296;
long long l2 = 72057594037927934;
long long l3 = l2 % l1;

long double d1 = static_cast<long double>(l1);
long double d2 = static_cast<long double>(l2);
long double d3 = fmod (d2, d1);

std::cout << "l1 = " << l1 << std::endl;
std::cout << "l2 = " << l2 << std::endl;
std::cout << "l3 = " << l3 << std::endl;

std::cout << std::endl;
std::cout << "d1 = " << std::setprecision(18) << d1 << std::endl;
std::cout << "d2 = " << std::setprecision(18) << d2 << std::endl;
std::cout << "d3 = " << std::setprecision(18) << d3 << std::endl;

return 0;

}
// -----------------------

Paavo Helde

unread,
Feb 11, 2016, 5:25:45 AM2/11/16
to
The root problem is that d3 gets rounded to a double at some point,
becoming 72057594037927936. With MSVC this happens already at d2
definition because in MSVC long double is the same as double. But with
gcc it should work in principle as long double has more precision there.

Anyway, it seems there are two problems:

1. <cmath> defines fmod() overloads in std:: namespace, so you need to
use std::fmod, not fmod. The latter (at least with gcc) only finds the C
version fmod(double, double). The std::fmod() works correctly with g++
4.6.2 on Linux, for example.

2. Even if you use std::fmod(), it seems that Cygwin g++ has not
implemented the long double version (it is lacking fmodl() as well), so
it is still falling back to the double version.







jacobnavia

unread,
Feb 11, 2016, 5:30:33 AM2/11/16
to
CYGWIN uses as its run time the CRTDLL.DLL software of Microsoft. Since
Microsoft does NOT implement long double, nothing that uses long double
will work under cygwin.

The compiler (gcc) does not know this and supposes that long double is
different than double.

Since printf/fmodl, etc do not work, there are since years always this
kinds of questions. Apparently the docs do not tell this very clearly.

DO NOT USE LONG DOUBLE WHEN USING CYGWIN!
Message has been deleted

Alex Vinokur

unread,
Feb 11, 2016, 5:40:56 AM2/11/16
to
Thanks.
0 new messages