Sample code which is valid and gets compiled by gcc but not by VS compiler:
#include <cmath>
int main()
{
float x = 1233.23;
x = round (x * 10) / 10;
return 0;
}
but for some reason, when I am compiling this in Visual Studio I get an error:
C3861: 'round': identifier not found
I do include even cmath as someone suggested here: http://www.daniweb.com/software-development/cpp/threads/270269/boss_loken.cpp147-error-c3861-round-identifier-not-found
Is this function in gcc only?
First of all, cmath is not guaranteed to bring round into the global namespace, so your code could fail, even with an up-to-date, standards compliant C or C++ implementation. To be sure, use std::round (or #include <math.h>.)
Note that your C++ compiler must support C++11 for std::round (<cmath>). A C compiler should support C99 for round (from <math.h>.) If your version of MSVC doesn't work after the fix I suggested, it could simply be that that particular version is pre-C++11, or is simply not standards compliant.
You also can use a boost library:
#include <boost/math/special_functions/round.hpp>
const double a = boost::math::round(3.45); // = 3.0
const int b = boost::math::iround(3.45); // = 3
Visual Studio 2010 (C99) doesn't support round but ceil and floor functions, so you may want to add your own function like;
long long int round(float a)
{
long long int result;
if (a-floor(a)>=0.5)
result = floor(a)+1;
else
result = floor(a);
return result;
};
The std::round nor #include <math.h> supported at the VS 2010 according to my experience.
I would use floor twice to get the correct rounded value,
long long int round(float a)
{
long long int result = (long long int)floor(a);
return result + (long long int)floor((a-result)*2)
};
Related
I am working on porting c code to c++. The below C program compiles successfully. But in c++, it throws an error. I know its really basic thing. I've more than 100 functions declared in this way. Is there any flag we can add to compile successfully instead of modifying all the functions.
OS: Windows
IDE: Visual Studio
int sum(m,n)
int m,n;
{
return m+n;
}
This is very old style C. Nobody should have been using this for the last 30 years. You can't compile this with a C++ compiler. There are no compiler flags whatsoever for this, at least in the compilers I'm aware of (clang, gcc, microsoft compilers).
You should transform all functions that have the form
int sum(m,n)
int m,n;
{
return m+n;
}
int to the form
int sum(int m, int n)
{
return m+n;
}
If you have 100 functions it should be doable.
But there may be many other problems because C++ is not an exact superset of C.
This SO article may be interesting for you: Function declaration: K&R vs ANSI
This question already has an answer here:
Is it a conforming compiler extension to treat non-constexpr standard library functions as constexpr?
(1 answer)
Closed 4 years ago.
I have written a c++ program as blow:
#include <iostream>
int main()
{
constexpr double a = 4.0;
constexpr double b = sqrt(a);
std::cout << b << std::endl;
return 0;
}
When I tried to compile this code with visual studio 2017, I got an error that says a function call must have a constant value in a constant expression. The bad line is "constexpr double b = sqrt(a);".
But when I used g++ to compile the same code, no error was reported.
What's the reason of the error? What's the different between g++ and vc++?
sqrt isn't a constexpr function so can't be used in a constexpr expression. GCC seems to have a special built in version of sqrt which is constexpr. Clang doesn't allow this code either:
https://godbolt.org/z/SvFEAW
sqrt is required to be not a constant expression so constexpr double b = sqrt(a); is not supposed to work. Clang does not build this code as well. You also need to include <cmath> header in order to use this function.
include cmath library since you using a sqrt() function
http://www.cplusplus.com/reference/cmath/
I have an application where I absolutely must use long double data type due to catastrophic truncation error when doing math with double precision. My testing procedures are going crazy because on windows long double with Visual Studio is just an alias to double, while on linux and OSX, long double is a real long double with nominally precision of 1e-19.
On mingw (windows port of GCC) is where I am confused. Mingw claims that LDBL_EPSILON has a precision of 1e-19, but googleing suggests that the mingw uses the c runtime that is actually just the microsoft c runtime which doesn't support real long doubles. Can anyone shed any light here?
EDIT: The crux of the problem is this: on mingw, if I call the math function log(long double x), is this just an alias to log(double x)? In either case, how could I write my own script to test this behavior and/or test for it?
Following code
#include <iostream>
#include <cmath>
int main(void)
{
long double y = 2.0L;
std::cout << sizeof(y) << std::endl;
long double q = sqrt(y);
std::cout << q << std::endl;
return 0;
}
produced output 16 1.41421, so far so good
Ran it throw preprocessor (-E option) and found out that internal, but different from double sqrt() function were called
using ::sqrt;
inline constexpr float sqrt(float __x)
{ return __builtin_sqrtf(__x); }
inline constexpr long double sqrt(long double __x)
{ return __builtin_sqrtl(__x); }
Same for log(), sin(), you name it
Thus, I believe MinGW support long double format in arithmetics as well as in math.functions, and this support is built-in, not libquadmath based
Just tried with MinGW (MinGW distro from nuwen, gcc/g++ 4.9.1, 64bit)
Following program
#include <iostream>
int main(void)
{
double x = 1.0;
long double y = 2.0L;
std::cout << sizeof(x) << std::endl;
std::cout << sizeof(y) << std::endl;
}
produced
8
16
I would guess, long double is supported and is different from standard double, thus
your computations might produce desired result
I've heard there are problems with printing long doubles on Windows due to using MS old runtime.
You might have to use casts or roll your own output routines
I want to check code inside math library function sqrt() how is it possible? I am using DEV C++ .
This stuff gets compiled into the toolchain runtime, but since GCC and its Windows port MinGW (which is what your Dev-C++ IDE invokes) are open-source, you can just take a look at the source.
Here it is for latest MinGW GCC; both versions appear to defer basically all of the work to the processor (which is not a great surprise, seeing as x86 — by way of the x87 part of the instruction set — supports square root calculations natively).
long double values
#include <math.h>
#include <errno.h>
extern long double __QNANL;
long double
sqrtl (long double x)
{
if (x < 0.0L )
{
errno = EDOM;
return __QNANL;
}
else
{
long double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
}
float values
#include <math.h>
#include <errno.h>
extern float __QNANF;
float
sqrtf (float x)
{
if (x < 0.0F )
{
errno = EDOM;
return __QNANF;
}
else
{
float res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
}
Square roots are calculated by the floating point unit of the processor so there is not much C++ to learn there...
EDIT:
x86 instructions
http://en.wikipedia.org/wiki/X86_instruction_listings
http://en.wikipedia.org/wiki/X87
FSQRT - Square root
Even back in the day: en.wikipedia.org/wiki/8087
If there's no source code for your sqrt(), you can always disassemble it. Inspecting the code would be one type of checking.
You can also write a test for sqrt(). That would be the other type of checking.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do you printf an unsigned long long int?
#include <cstdio>
int main ()
{
unsigned long long int n;
scanf("%llu",&n);
printf("n: %llu\n",n);
n /= 3;
printf("n/3: %llu\n",n);
return 0;
}
Whatever I put in input, I get very strange output, for example:
n: 1
n/3: 2863311531
or
n: 2
n/3: 2863311531
or
n: 1000
n/3: 2863311864
What's the reason? How should I do this correctly?
(g++ 3.4.2, Win XP)
The problem is that MinGW relies on the msvcrt.dll runtime. Even though the GCC compiler supports C99-isms like long long the runtime which is processing the format string doesn't understand the "%llu" format specifier.
You'll need to use Microsoft's format specifier for 64-bit ints. I think that "%I64u" will do the trick.
If you #include <inttypes.h> you can use the macros it provides to be a little more portable:
int main ()
{
unsigned long long int n;
scanf("%"SCNu64, &n);
printf("n: %"PRIu64"\n",n);
n /= 3;
printf("n/3: %"PRIu64"\n",n);
return 0;
}
Note that MSVC doesn't have inttypes.h until VS 2010, so if you want to be portable to those compilers you'll need to dig up your own copy of inttypes.h or take the one from VS 2010 (which I think will work with earlier MSVC compilers, but I'm not entirely sure). Then again, to be portable to those compilers, you'd need to do something similar for the unsigned long long declaration, which would entail digging up stdint.h and using uint64_t instead of unsigned long long.