c++ changing implicit conversion from double to int - c++

I have code which has a lot of conversions from double to int . The code can be seen as
double n = 5.78;
int d = n; // double implicitly converted to a int
The implicit conversion from double to int is that of a truncation which means 5.78 will be saved as 5 . However it has been decided to change this behavior with custom rounding off .
One approach to such problem would be to have your own DOUBLE and INT data types and use conversion operators but alas my code is big and I am not allowed to do much changes . Another approach i thought of was to add 0.5 in each of the numbers but alas the code is big and i was changing too much .
What can be a simple approach to change double to int conversion behaviour which impact the whole code.

You can use uniform initialization syntax to forbid narrowing conversions:
double a;
int b{a}; // error
If you don't want that, you can use std::round function (or its sisters std::ceil/std::floor/std::trunc):
int b = std::round(a);
If you want minimal diff changes, here's what you can do. Please note, though, that this is a bad solution (if it can be named that), and much more likely leaving you crashing and burning due to undefined behavior than actually solving real problems.
Define your custom Int type that handles conversions the way you want it to:
class MyInt
{
//...
};
then evilly replace each occurence of int with MyInt with the help of preprocessor black magic:
#define int MyInt
Problems:
if you accidentally change definitions in the standard library - you're in the UB-land
if you change the return type of main - you're in the UB-land
if you change the definition of a function but not it's forward declarations - you're in the UB/linker error land. Or in the silently-calling-different-overload-land.
probably more.

Do something like this:
#include <iostream>
using namespace std;
int myConvert (double rhs)
{
int answer = (int)rhs; //do something fancier here to meet your needs
return answer;
}
int main()
{
double n = 5.78;
int d = myConvert(n);
cout << "d = " << d << endl;
return 0;
}
You can make myConvert as fancy as you want. Otherwise, you could define your own class for int (e.g. myInt class) and overload the = operator to do the right conversion.

Related

why int a= 4i; not report an syntax error(c++)

#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int a = 232u;
int b = 4i;
cout << a << endl << b;
}
I was review basic of cpp, As the screen shot I took, I tried to sign an unsigned int to a int which was fine, then I tried change that u to i and waiting for a error, but there's no error and output was 0. There's no define of i. So what happened.
I'm using xcode on mac, last picture is the build settings.
C++ has a concept of literals, this is used to describe the type of a value. For example, integer literal can be used to write I want a integer 1 with a type unsigned int. We will write it 1u.
In your case, your are probably using a GNU extension for imaginary constants. What you write don't compile in C++ standard.
The good way to use complex literal in C++ standard is to include include <complex>. And to use std::complex_literals, this is only possible in C++14.
The suffix i denotes the imaginary part of a complex number; when assigning an (implicitly) constructed complex number to integral value, only the real part is taken.
Hence, the following expression yields 0:
int b = 4i; // gives 0; real-part of 4i is 0, imaginary-part is 4: casting to int gives the real part, i.e. 0
But:
int x = 4i*4i; // gives -16; as i means the square root of -1, i*i yields -1; so 4i*4i = -16
Note that this works even without including <complex>.

creating a literal for a Point - C++

I am trying to do a simple library where the object is a point on the xy-axis.
I want to be able to use literals like this:
Point a = (3,4);
where (3,4) is a point literal.
I read about user defined literals, but (as I understood) this seems to be impossible.
May be "(3,4)"_P is possible as I understand it.
However, I found on this page interesting use of user defined literals as follows:
#include <iostream>
#include <complex>
int main()
{
using namespace std::complex_literals;
std::complex<double> c = 1.0 + 1i;
std::cout << "abs" << c << " = " << abs(c) << '\n';
}
I can under stand the part 1i as a user defined literal, but not the whole thing 1.0 + 1i.
What I am missing, and what is the nearest possible way of getting a literal similar to (x,y) without using ".
As Some programmer dude shows, the best way is to use uniform initialization.
However, just for the fun of it, you can (sort of) do this with User Defined Literals. My idea is to to have 2 literals for each coordinate and overload operator+ between them to create the point.
Remember, this is just for fun, don't use this in a real code:
struct Px { int x; };
struct Py { int y; };
struct Point {
int x;
int y;
};
constexpr auto operator""_px(unsigned long long x) -> Px { return Px{(int)x}; }
constexpr auto operator""_py(unsigned long long y) -> Py { return Py{(int)y}; }
constexpr auto operator+(Px x, Py y) -> Point { return Point{x.x, y.y}; }
then you can have:
auto p = 3_px + 4_py; // p is deduced to type `Point`
Of course this is just a rough framework. Read this great article to learn more about UDLs. You would need to deal with the narrowing conversion in a better way and propper use namespaces to make it a better solution.
As a bonus, you could also use operator, to create a syntax more appropriate to what you had in mind. But, don't do this, as overloading operator, is just evil:
auto operator,(Px x, Py y) -> Point { return Point{x.x, y.y}; }
auto p = (2_px, 1_py); // p is deduced to type `Point`
You can't make up literals on your own, only create suffixes for literals. Like the shown 1i or the standard language f as in 1.0f. (See e.g. this user-defined literal reference for more information.)
What you can to is to use uniform initialization doing something like
Point a = { 3, 4 }; // note the use of curly-braces
Depending on what Point is you might need to add a suitable constructor to make it work.
You have 3 options
Point p = { 1,2 };
Point p2{ 1,2 };
Point p3(1,2);

Composite function in C++

I am a beginner in C++ and want to do simple example of composite function.
For example, in MATLAB, I can write
a = #(x) 2*x
b = #(y) 3*y
a(b(1))
Answer is 6
I searched following questions.
function composition in C++ / C++11 and
Function Composition in C++
But they are created using advanced features, such as templates, to which I am not much familiar at this time. Is there a simple and more direct way to achieve this? In above MATLAB code, user does not need to know implementation of function handles. User can just use proper syntax to get result. Is there such way in C++?
** Another Edit:**
In above code, I am putting a value at the end. However, if I want to pass the result to a third function, MATLAB can still consider it as a function. But, how to do this in C++?
For example, in addition to above code, consider this code:
c = #(p,q) a(p)* b(q) %This results a function
c(1,2)
answer=12
d = #(r) a(b(r))
d(1)
answer=6
function [ output1 ] = f1( arg1 )
val = 2.0;
output1 = feval(arg1,val)
end
f1(d)
answer = 12
In this code, c takes two functions as input and d is composite function. In the next example, function f1 takes a function as argument and use MATLAB builtin function feval to evaluate the function at val.
How can I achieve this in C++?
How about:
#include <iostream>
int main(int, char**)
{
auto a = [](int x) { return 2 * x; };
auto b = [](int y) { return 3 * y; };
for (int i = 0; i < 5; ++i)
std::cout << i << " -> " << a(b(i)) << std::endl;
return 0;
}
Perhaps I'm misunderstanding your question, but it sounds easy:
int a(const int x) { return x * 2; }
int b(const int y) { return y * 3; }
std::cout << a(b(1)) << std::endl;
Regarding your latest edit, you can make a function return a result of another function:
int fun1(const int c) { return a(c); }
std::cout << fun1(1) << std::endl;
Note that this returns a number, the result of calling a, not the function a itself. Sure, you can return a pointer to that function, but then the syntax would be different: you'd have to write something like fun1()(1), which is rather ugly and complicated.
C++'s evaluation strategy for function arguments is always "eager" and usually "by value". The short version of what that means is, a composed function call sequence such as
x = a(b(c(1)));
is exactly the same as
{
auto t0 = c(1);
auto t1 = b(t0);
x = a(t1);
}
(auto t0 means "give t0 whatever type is most appropriate"; it is a relatively new feature and may not work in your C++ compiler. The curly braces indicate that the temporary variables t0 and t1 are destroyed after the assignment to x.)
I bring this up because you keep talking about functions "taking functions as input". There are programming languages, such as R, where writing a(b(1)) would pass the expression b(1) to a, and only actually call b when a asked for the expression to be evaluated. I thought MATLAB was not like that, but I could be wrong. Regardless, C++ is definitely not like that. In C++, a(b(1)) first evaluates b(1) and then passes the result of that evaluation to a; a has no way of finding out that the result came from a call to b. The only case in C++ that is correctly described as "a function taking another function as input" would correspond to your example using feval.
Now: The most direct translation of the MATLAB code you've shown is
#include <stdio.h>
static double a(double x) { return 2*x; }
static double b(double y) { return 3*y; }
static double c(double p, double q) { return a(p) * b(q); }
static double d(double r) { return a(b(r)); }
static double f1(double (*arg1)(double))
{ return arg1(2.0); }
int main()
{
printf("%g\n", a(b(1))); // prints 6
printf("%g\n", c(1,2)); // prints 12
printf("%g\n", d(1)); // prints 6
printf("%g\n", f1(d)); // prints 12
printf("%g\n", f1(a)); // prints 4
return 0;
}
(C++ has no need for explicit syntax like feval, because the typed parameter declaration, double (*arg1)(double) tells the compiler that arg1(2.0) is valid. In older code you may see (*arg1)(2.0) but that's not required, and I think it makes the code less readable.)
(I have used printf in this code, instead of C++'s iostreams, partly because I personally think printf is much more ergonomic than iostreams, and partly because that makes this program also a valid C program with the same semantics. That may be useful, for instance, if the reason you are learning C++ is because you want to write MATLAB extensions, which, the last time I checked, was actually easier if you stuck to plain C.)
There are significant differences; for instance, the MATLAB functions accept vectors, whereas these C++ functions only take single values; if I'd wanted b to call c I would have had to swap them or write a "forward declaration" of c above b; and in C++, (with a few exceptions that you don't need to worry about right now,) all your code has to be inside one function or another. Learning these differences is part of learning C++, but you don't need to confuse yourself with templates and lambdas and classes and so on just yet. Stick to free functions with fixed type signatures at first.
Finally, I would be remiss if I didn't mention that in
static double c(double p, double q) { return a(p) * b(q); }
the calls to a and b might happen in either order. There is talk of changing this but it has not happened yet.
int a(const int x){return x * 2;}
int b(const int x){return x * 3;}
int fun1(const int x){return a(x);}
std::cout << fun1(1) << std::endl; //returns 2
This is basic compile-time composition. If you wanted runtime composition, things get a tad more involved.

What is the purpose of a declaration like int (x); or int (x) = 10;

If you look at the grammar for *declarator*s in §8/4 you'll notice that a noptr-declarator can be written as (ptr-declarator), that is, it can be written as (declarator-id), which validates declarations like the ones in the title. As matter of fact this code compiles without a problem:
#include <iostream>
struct A{ int i;};
int (x) = 100;
A (a) = {2};
int main()
{
std::cout << x << '\n';
std::cout << a.i << '\n';
}
But what is the purpose of allowing these parentheses when a pointer (to an array or to a function) is not involved in the declaration?
The fact that this rule is applicable in your case is not deliberate: It's ultimately a result of keeping the grammar simple. There is no incentive to prohibit declarations such as yours, but there are great disincentives to complicate rules, especially if those are intricate as they are.
In short, if you don't want to use this needlessly obfuscated syntax, don't.
C++ rarely forces you to write readable code.
Surprisingly there are scenarios in which parentheses can save the day, though:
std::string foo();
namespace detail
{
int foo(long); // Another foo
struct Bar
{
friend std::string ::foo(); // Doesn't compile for obvious reasons.
friend std::string (::foo)(); // Voilà!
};
}
You're asking the wrong question. The correct question is:
What is the purpose of disallowing such a declaration?
The answer is: there is none.
So, given that this syntax is allowed as a side-effect of rules elsewhere, this is what you get.

Does a simple cast to perform a raw copy of a variable break strict aliasing?

I've been reading about strict aliasing quite a lot lately. The C/C++ standards say that the following code is invalid (undefined behavior to be correct), since the compiler might have the value of a cached somewhere and would not recognize that it needs to update the value when I update b;
float *a;
...
int *b = reinterpret_cast<int*>(a);
*b = 1;
The standard also says that char* can alias anything, so (correct me if I'm wrong) compiler would reload all cached values whenever a write access to a char* variable is made. Thus the following code would be correct:
float *a;
...
char *b = reinterpret_cast<char*>(a);
*b = 1;
But what about the cases when pointers are not involved at all? For example, I have the following code, and GCC throws warnings about strict aliasing at me.
float a = 2.4;
int32_t b = reinterpret_cast<int&>(a);
What I want to do is just to copy raw value of a, so strict aliasing shouldn't apply. Is there a possible problem here, or just GCC is overly cautious about that?
EDIT
I know there's a solution using memcpy, but it results in code that is much less readable, so I would like not to use that solution.
EDIT2
int32_t b = *reinterpret_cast<int*>(&a); also does not work.
SOLVED
This seems to be a bug in GCC.
If you want to copy some memory, you could just tell the compiler to do that:
Edit: added a function for more readable code:
#include <iostream>
using std::cout; using std::endl;
#include <string.h>
template <class T, class U>
T memcpy(const U& source)
{
T temp;
memcpy(&temp, &source, sizeof(temp));
return temp;
}
int main()
{
float f = 4.2;
cout << "f: " << f << endl;
int i = memcpy<int>(f);
cout << "i: " << i << endl;
}
[Code]
[Updated Code]
Edit: As user/GMan correctly pointed out in the comments, a full-featured implementation could check that T and U are PODs. However, given that the name of the function is still memcpy, it might be OK to rely on your developers treating it as having the same constraints as the original memcpy. That's up to your organization. Also, use the size of the destination, not the source. (Thanks, Oli.)
Basically the strict aliasing rules is "it is undefined to access memory with another type than its declared one, excepted as array of characters". So, gcc isn't overcautious.
If this is something you need to do often, you can also just use a union, which IMHO is more readable than casting or memcpy for this specific purpose:
union floatIntUnion {
float a;
int32_t b;
};
int main() {
floatIntUnion fiu;
fiu.a = 2.4;
int32_t &x = fiu.b;
cout << x << endl;
}
I realize that this doesn't really answer your question about strict-aliasing, but I think this method makes the code look cleaner and shows your intent better.
And also realize that even doing the copies correctly, there is no guarantee that the int you get out will correspond to the same float on other platforms, so count any network/file I/O of these floats/ints out if you plan to create a cross-platform project.