C++ error: invalid suffix '.d' on floating constant - c++

Hello I have the following declared arrays in C++:
int arr[5] = {1,2,3,4,0};
float arr2[10] = {1.2f,0.0f,2.0f,1.4f,0.0f,4.2f,5.3f,0.0f,0.0f,0.0f};
double arr3[6] = {0.0d,0.0d,5.3d,0.0d,0.0d,0.5d};
When I compile this code the compiler returns the following error:
error: invalid suffix '.d' on floating constant
I tried compiling using the flag -std=c++11 to try and see if it worked on C++ 11 but I get the same error. Can someone tell me where the error is? Thank you :)

Floating point literal suffixes are:
(no suffix) defines double
f F defines float
l L defines long double
Supposed you put the d to make the literal a double, you can remove it. I suppose gcc offers it as extension for the sake of consistency (allows to use a suffix also for doubles), but also gcc will accept no suffix and the type of the literal will be double.

Related

What's the difference between abs and fabs?

I checked the difference between abs and fabs on python here
As I understand there are some difference regarding the speed and the passed types, but my question related to native c++ on V.S.
Regarding the V.S.
I tried the following on Visual Studio 2013 (v120):
float f1= abs(-9.2); // f = 9.2
float f2= fabs(-9); // Compile error [*]
So fabs(-9) it will give me a compiler error, but when I tried to do the following:
double i = -9;
float f2= fabs(i); // This will work fine
What I understand from the first code that it will not compile because fabs(-9) need a double, and the compiler could not convert -9 to -9.0, but in the second code the compiler will convert i=-9 to i=-9.0 at compile time so fabs(i) will work fine.
Any better explanation?
Another thing, why the compiler can't accept fabs(-9) and convert the int value to double automatically like what we have in c#?
[*]:
Error: more than one instance of overloaded function "fabs" matches the argument list:
function "fabs(double _X)"
function "fabs(float _X)"
function "fabs(long double _X)"
argument types are: (int)
In C++, std::abs is overloaded for both signed integer and floating point types. std::fabs only deals with floating point types (pre C++11). Note that the std:: is important; the C function ::abs that is commonly available for legacy reasons will only handle int!
The problem with
float f2= fabs(-9);
is not that there is no conversion from int (the type of -9) to double, but that the compiler does not know which conversion to pick (int -> float, double, long double) since there is a std::fabs for each of those three. Your workaround explicitly tells the compiler to use the int -> double conversion, so the ambiguity goes away.
C++11 solves this by adding double fabs( Integral arg ); which will return the abs of any integer type converted to double. Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.
In general, just use std::abs, it will do the right thing. (Interesting pitfall pointed out by #Shafik Yaghmour. Unsigned integer types do funny things in C++.)
With C++ 11, using abs() alone is very dangerous:
#include <iostream>
#include <cmath>
int main() {
std::cout << abs(-2.5) << std::endl;
return 0;
}
This program outputs 2 as a result. (See it live)
Always use std::abs():
#include <iostream>
#include <cmath>
int main() {
std::cout << std::abs(-2.5) << std::endl;
return 0;
}
This program outputs 2.5.
You can avoid the unexpected result with using namespace std; but I would adwise against it, because it is considered bad practice in general, and because you have to search for the using directive to know if abs() means the int overload or the double overload.
My Visual C++ 2008 didn't know which to choice from long double fabs(long double), float fabs(float), or double fabs(double).
In the statement double i = -9;, the compiler will know that -9 should be converted to double because the type of i is double.
abs() is declared in stdlib.h and it will deal with int value.
fabs() is declared in math.h and it will deal with double value.

Clang 3.1 and user defined literals

Clang 3.1 claims to support user defined literals. I can define this:
int operator"" _tryit(long double n) { return int(n); }
but when I try to use it I get an error:
int m = 5_tryit;
Invalid suffix '_tryit' on integer constant
5 cannot be implicitly converted to a long double in your case. You need to change it to 5.0 to make it a long double or explicitly invoke the function yourself for the implicit conversion to work:
int m = 5.0_tryit;
OR
int n = operator"" _tryit(5);
(tested both with clang version 3.1 (trunk) (llvm/trunk 155821))
This SO question has a good explanation of the rules.
(Also, as abarnert mentions, make sure you are passing the -std=c++11 flag to the compiler when compiling).

Locating numerical errors due to Integer division

Is there a g++ warning or other tool that can identify integer division (truncation toward zero)? I have thousands of lines of code with calculations that inevitably will have numerical errors typically due to "float = int/int" that need to be located. I need a reasonable method for finding these.
Try -Wconversion.
From gcc's man page:
Warn for implicit conversions that may
alter a value. This includes
conversions between real and integer,
like "abs (x)" when "x" is "double";
conversions between signed and
unsigned, like "unsigned ui = -1"; and
conversions to smaller types, like
"sqrtf (M_PI)". Do not warn for
explicit casts like "abs ((int) x)"
and "ui = (unsigned) -1", or if the
value is not changed by the conversion
like in "abs (2.0)". Warnings about
conversions between signed and
unsigned integers can be disabled by
using -Wno-sign-conversion.
For C++, also warn for conversions
between "NULL" and non-pointer types;
confusing overload resolution for
user-defined conversions; and
conversions that will never use a type
conversion operator: conversions to
"void", the same type, a base class or
a reference to them. Warnings about
conversions between signed and
unsigned integers are disabled by
default in C++ unless
-Wsign-conversion is explicitly enabled.
For the following sample program (test.cpp), I get the error test.cpp: In function ‘int main()’:
test.cpp:7: warning: conversion to ‘float’ from ‘int’ may alter its value.
#include <iostream>
int main()
{
int a = 2;
int b = 3;
float f = a / b;
std::cout << f;
return 0;
}
I have a hard time calling these numerical errors. You asked for integer calculations, and got the correct numbers for integer calculations. If those numbers aren't acceptable, then ask for floating point calculations:
int x = 3;
int y = 10;
int z = x / y;
// "1." is the same thing as "1.0", you may want to read up on
// "the usual arithmetic conversions." You could add some
// parentheses here, but they aren't needed for this specific
// statement.
double zz = 1. * x / y;
This page contains info about g++ warnings. If you've already tried -Wall then the only thing left could be the warnings in this link. On second look -Wconversion might do the trick.
Note: Completely edited the response.
Remark on -Wconversion of gcc:
Changing the type of the floating point variable from float to double makes the warning vanish:
$ cat 'file.cpp'
#include <iostream>
int main()
{
int a = 2;
int b = 3;
double f = a / b;
std::cout << f;
}
Compiling with $ g++-4.7 -Wconversion 'file.cpp' returns no warnings (as $ clang++ -Weverything 'file.cpp').
Explanation:
The warning when using the type float is not returned because of the totally valid integer arithmetics, but because float cannot store all possible values of int (larger ones cannot be captured by float but by double). So there might be a change of value when assigning RHS to f in the case of float but not in the case of double. To make it clear: The warning is not returned because of int/int but because of the assignment float = int.
For this see following questions: what the difference between the float and integer data type when the size is same in java, Storing ints as floats and Rounding to use for int -> float -> int round trip conversion
However, when using float -Wconversion could still be useful to identify possible lines which are affected but is not comprehensive and is actually not intended for that. For the purpose of -Wconversion see docs/gcc/Warning-Options.html and here gcc.gnu.org/wiki/NewWconversion
Possibly of interest is also following discussion 'Implicit casting Integer calculation to float in C++'
The best way to find such error is to have really good unit tests. All alternatives are not good enough.
Have a look at this clang-tidy detection.
It catches cases like this:
d = 32 * 8 / (2 + i);
d = 8 * floatFunc(1 + 7 / 2);
d = i / (1 << 4);

Problem with sprintf function, last parameters are wrong when written

So I use sprintf
sprintf(buffer, "%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID, dDistance, nConfig);
But when I print the buffer I get the 2 last parameters wrong, they are lets suppose to be 35.0000 and 0 and in the string they are 0.00000 and 10332430 and my buffer is long enough and all the other parameters are good in the string
Any idea? Is there a length limit to sprintf or something?
I checked the types of all the numbers and they are right, but what seems to be the problem is the dDistance. When I remove it from the sprint, the nConfig gets the right value in the string, but when I remove nConfig, dDistance still doesn't get the right value. I checked and dDistance is a double. Any idea?
Since people don't seem to believe me I did this :
char test[255]={0};
int test1 = 2;
double test2=35.00;
int test3 = 0;
sprintf(test,"%d|%f|%d",test1,test2,test3);
and I get this in my string:
2|0.000000|1078034432
I'd check to make sure your argument types match up with your format string elements. Trying to display a double as an integer type (%d) or vice versa can give you strange output.
Are you sure your data types match your format spec?
Try printing out your data, that is, create a printf with the same format and see what happens that is:
printf("%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID,dDistance, nConfig);
Try using streams, for example
stringstream ss;
ss << x << "|" << y << "|" << z << "|" << u << "|" << v << "|" << w << "|"
<< nID << "|"<< dDistance << "|"<< nConfig;
string s = ss.str();
and then do something with s;
What size are long and int?
If nID is a long being printed with an 'int' format and sizeof(int) != sizeof(long) then you get misaligned data access (in the sense that the alignment is not correct) from there on.
Which compiler are you using? GCC should diagnose the problem without difficulty if that is the trouble. Similarly, if nID is a 'long long', you could have problems.
To answer your question - yes, there is an lower-bound on the upper-limit of the length of string that sprintf() must be able to handle. The number is 509 for C89 systems, and 4095 for C99 systems.
To be precise, C99 says (fprintf(), section §7.19.6.1, para 15):
The number of characters that can be produced by any single conversion shall be at least
4095.
There is no further qualification on sprintf().
With fixed version of amended example converted into compilable code:
#include <stdio.h>
int main(void)
{
char test[255] = {0};
int test1 = 2;
double test2 = 35.00;
int test3 = 0;
sprintf(test, "%d|%f|%d", test1, test2, test3);
puts(test);
return(0);
}
I get the output I would expect:
2|35.000000|0
To be getting the output you show, you have to be working with a very weird setup.
What platform are you on?
The behaviour you are showing indicates that the sprintf() function you are using is confused about the alignment or size of something. Do you have a prototype in scope - that is, have you #included <stdio.h>? With GCC, I get all sorts of warnings when I omit the header:
x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:9: warning: implicit declaration of function ‘puts’
But even with test2 redefined as a float I get the correct result.
If I change test2 into a long double, then I get a different set of warnings and a different result:
x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:8: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long double’
x.c:9: warning: implicit declaration of function ‘puts’
2|0.000000|0
This is closer to what you are seeing, though far from identical.
Since we don't have the platform information, I'm suspicious that you are working with a truly ancient (or do I mean buggy?) version of C. But I'm still at something of a loss to see how you get what you show - unless you're on a big-endian machine (I'm testing on Intel Mac with MacOS X 10.6.2) ...pause... on a SPARC machine running Solaris 10, without #include <stdio.h> and with long double test2 = 35.0;, I get:
gcc -O x.c -o x && ./x
x.c: In function 'main':
x.c:8: warning: incompatible implicit declaration of built-in function 'sprintf'
2|-22446048024026502740613283801712842727785152907992454451420278635613183447049251888877319095301502091725503415850736723945766334416305449970423980980099172087880564051243997662107950451281495566975073444407658980167407319222477077473080454782593800009947058951029590025152409694784570786541673131117073399808.000000|0
That's different; it also generates 321 characters of output, so there's a buffer overflow in there - it is better to use 'snprintf()' to prevent that from occurring. When things are declared properly, of course, I get the expected result.
So, can you post compilable code that shows your problem, instead of a snippet that does not? And can you identify your platform - machine type, operating system version, compiler version (and maybe C library version)?
Is dDistance of type double? It looks like your %f is only grabbing four bytes of a double and then the next four bytes are treated as an integer, the real integer value is then ignored.
This question is tagged C++; are you able to use std::ostringstream which would eliminate any possible problems with the conversion string?

sqrt(int_value + 0.0) -- Does it have a purpose?

while doing some homework in my very strange C++ book, which I've been told before to throw away, had a very peculiar code segment. I know homework stuff always throws in extra "mystery" to try to confuse you like indenting 2 lines after a single-statement for-loop. But this one I'm confused on because it seems to serve some real-purpose.
basically it is like this:
int counter=10;
...
if(pow(floor(sqrt(counter+0.0)),2) == counter)
...
I'm interested in this part especially:
sqrt(counter+0.0)
Is there some purpose to the +0.0? Is this the poormans way of doing a static cast to a double? Does this avoid some compiler warning on some compiler I do not use? The entire program printed the exact same thing and compiled without warnings on g++ whenever I left out the +0.0 part. Maybe I'm not using a weird enough compiler?
Edit:
Also, does gcc just break standard and not make an error for Ambiguous reference since sqrt can take 3 different types of parameters?
[earlz#EarlzBeta-~/projects/homework1] $ cat calc.cpp
#include <cmath>
int main(){
int counter=0;
sqrt(counter);
}
[earlz#EarlzBeta-~/projects/homework1] $ g++ calc.cpp
/usr/lib/libstdc++.so.47.0: warning: strcpy() is almost always misused, please use strlcpy()
/usr/lib/libstdc++.so.47.0: warning: strcat() is almost always misused, please use strlcat()
[earlz#EarlzBeta-~/projects/homework1] $
Also, here is the relevant part of my system libraries cmath I'm not too keen on templates, so I'm not sure what it's doing
using ::sqrt;
inline float
sqrt(float __x)
{ return __builtin_sqrtf(__x); }
inline long double
sqrt(long double __x)
{ return __builtin_sqrtl(__x); }
template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
sqrt(_Tp __x)
{ return __builtin_sqrt(__x);
Is this the poormans way of doing a static cast to a double?
Yes.
You can't call sqrt with an int as its parameter, because sqrt takes a float, double, or long double. You have to cast the int to one of those types, otherwise the call is ambiguous.
the reason for the expression counter + 0.0 is to explicitly make it a real number. if we donot add 0.0 the compiler will do implicit conversion
It's just another way to cast to a double. This is because sqrt doesn't accept ints. Because a double is higher it will merge the int into the 0.0. The same way can be done for converting from (int,double,float) to string.
double n = 0;
string m = ""+n;