more efficient cpp code - c++

I'm trying to solve a problem from the site open.kattis.com https://open.kattis.com/problems/different
the problem is you take in two non-negative integers from 0 to 10^15 and you calculate the difference. I wrote this and it calculates it correctly, but it is not fast enough, how can I make it faster?
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
long long int a, b;
while(a != 0){
cin >> a >> b;
if (a > b) { cout << a-b << endl;}
else{ cout << b-a << endl;}
}
return 0;
}

The real performance hit, if ran many many times would come from the 'endl' actually, because while it adds a '\n' at the end, it also flushes the stream. Any other micro optimization is quite meaningless at best, I'm sure the compiler is smart enough to put a fast enough code in it's place.
EDIT: Could also add std::ios::sync_with_stdio(false); if you are REALLY desperate for potential performance increase. This prevents the synchronization between C style streams. See: sync

Rather than doing a comparison to see which is bigger, which takes more time, you could just forget about which is bigger and calculate the difference anyway: cout << a-b << ends; If b is larger than a then yes you will end up with a negative result. In which case, multiply it by -1. I work mainly in C but I think in C++, it would look something like this: first store the result of the calculation in a variable 'x' long long int x = a-b, then if (x < 0) { x *= -1 ;}. This should work if my code is correct; I'm not sure if it will be much faster but it's definitely worth a try.
EDIT: Or, like #user64322 said, you could do the same as above, but rather than multiplying by -1, just take the absolute value, which is the same, but quicker.

In addition to the others' suggestions, an obvious thing you can do is use argv to take command line arguments at startup (e.g. ./PrintDiffQuick 10 5 would print 5) instead of blocking execution while waiting for user input.
#include <cinttypes>
#include <iostream>
int main(int argc, const char **argv)
{
std::ios::sync_with_stdio(false);
std::cout << std::imaxabs(std::strtoimax(argv[1], nullptr, 10) -
std::strtoimax(argv[2], nullptr, 10)) << '\n';
return 0;
}

Related

how to take a double's fraction part and turn it into an integer? (c++)

my goal is to turn a double's fraction part into an integer, for example: turn 0.854 into 854 or turn 0.9321 into 9321 (the whole part of the double is always 0)
i was doing it like this, but i dont know how to fill the while's parameters to make it stop when variable x becomes a whole number without a fraction:
double x;
cin >> x;
while(WHAT DO I TYPE HERE TO MAKE IT STOP WHEN X BECOMES A WHOLE NUMBER){
x *= 10;
}
it would be best if i could do it with a loop, but if it is not possible, i am open to other suggestions :)
That question has no answer in a mathematical/logical sense. You have to read how floating point numbers in computers work, see e.g.
https://en.wikipedia.org/wiki/Floating-point_arithmetic
and understand that they are not decimal point numbers in memory. A floating point number in memory consists of three actual numbers: significant * base^{exponent} and according to IEEE the base used is "2" in basically any modern floating point data, but in even more generality, the base can be anything. Thus, whatever you have in your mind, or even see on your screen as output, is a misleading representation of the data in memory. Your question is, thus, mainly a misconception of how floating point numbers in computers work...
Thus, what you specifically ask for does in general not exist and cannot be done.
However, there may be special application for output formatting or whatever where something like this may make sense -- but then the specific goal must be clearly stated in the question here. And in some of such cases, using a "string-based" approach, as you suggested, will work. But this is not an answer to your generic question and has the high potential to also mislead others in the future.
Actually, one way to make your question obvious and clear is to also specify a fixed desired precision, thus, numbers after the decimal point. Then the answer is quite trivially and correctly:
long int value = fraction * pow(10, precision);
In this scenario you know 100% what your are doing. And if you really like you could subsequently remove zeros from the right side...
int nTrailingZeros = 0;
while (value%10 == 0) {
value /= 10;
++nTrailingZeros;
}
However there is another principle problem on a numerical level: there is no mathematical difference between, e.g., 000003 and just 3, thus in any such application the input 0.000003 will give the same results as 0.0003 or 0.3 etc. This cannot be a desired functionality... it is pretty useless to ask about the *value of the fractional part of a floating point number. But, since we have a known precision`, we can do:
cout << setw(precision-ntrailing) << setfill('0') << value << endl;
which will fill in the eventually missing leading zeros.
See this complete tested test code
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
double v = 0.0454243252;
int precision = 14;
long int value = v*pow(10,precision);
cout << value << endl;
// 4542432520000
int nTrailingZeros = 0;
while (value%10 == 0) {
value /= 10;
++nTrailingZeros;
}
cout << value << endl;
// 454243252
cout << setw(precision-ntrailing) << setfill('0') << value << endl;
// 0454243252
}
Here is a possible approach:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main()
{
cout << "Enter Number: ";
double user_input;
cin >> user_input;
int user_input_to_int = int(user_input);
double decimal_value = user_input - user_input_to_int;
ostringstream oss;
oss << std::noshowpoint << decimal_value;
string num_str = oss.str();
int str_length = num_str.size()-2;
int multiplier = 1;
for (int x = 0; x < str_length; x++)
{
multiplier *= 10;
}
cout << "\n";
cout << "Whole number: " << user_input_to_int << endl;
cout << "Decimal value: " << decimal_value*multiplier << endl;
}
Compare the difference between double and integer part. It is working only if x is less than 2^63.
while (x - long long(x) > 0)
find 2 real numbers find the fractional part smaller than these numbers

Time Limit Exceeded in C++ Online Judge

I just sent the solution to a problem COJ written in C ++. The problem is this link: http://coj.uci.cu/24h/problem.xhtml?pid=1839
This is my solution:
#include<iostream>
using namespace std;
unsigned int t, n;
int main(){
cin >> t;
while(t > 0 && cin >> n){
cout<< ( n * 8 ) + 42 << endl;
t--;
}
return 0;
}
To this the judge online of COJ says: "Time Limit Exceeded". Can someone explain why?
Your could try to get rid of std::endl because it is slow. Instead, you use '\n'. The code is below:
#include<iostream>
using namespace std;
unsigned int t, n;
int main(){
cin >> t;
while(t > 0 && cin >> n){
cout<< ( n * 8 ) + 42 << '\n';
t--;
}
cout.flush();
return 0;
}
Or you could try printf() to fasten your I/O.
This algorithm grows linearly, it should not be a limit factor. I believe I/O is the limiting factor. If you could find a algorithm that is log N, please tell me.
Someone vote it down because they believe doing I/O with standard out(stdout) is fast. However, std::endl flush after every iteration, which makes it slow.
Another idea is to use recursion, and you hope the judge system has good optimization on tail recursion(it is possible.). It may get a little faster, too.
On your own computer, you could even try to profile it to find the limiting factor, and if it is I/O, try the way above.
If it is still not fast enough, get rid of object-oriented design, use C and write direct to stdout instead use printf.
Good luck!

Need help cleaning up fibonacci sequence using C++ please

I'm still very new to C++ still and decided to make a fibonacci sequence. It worked (Woo!) but it doesn't work as well as I would like it to.
what I mean by that is say for example I told my program to count the first 10 terms of the sequence I will get
"0, 1, 1" and then I have to press enter for each additional number until it hits ten in which case the program returns 0 and ends.
How do I get the program to display all the numbers I want to without hitting enter for each additional one?
Here is my script:
#include <iostream>
using namespace std;
int main()
{
int FibNum;
cout << "How many numbers of the Fibonacci Sequence would you like to see? \n\n";
cin>> FibNum;
cin.ignore();
int a = 0;
int b = 1;
int c = 2;
cout << "Fibonacci Sequence up to " << FibNum << " terms.\n\n";
cout << a << "\n" << b << "\n";
for (int c = 2; c < FibNum; c++) {
int d = a + b;
cout << d;
cin.ignore();
a = b;
b = d;
}
}
Thanks in advance for any help!
P.s. Also if you notice anything terrible I'm doing please feel free to correct me, I'm very aware I'm probably doing a lot wrong, I'm just trying to learn. :]
A few things:
1) Remove int c = 2; as you're re-defining c inside the for loop.
2) Drop the line cin.ignore();: in your for loop: that will fix your "enter" problem; that line waits for some input then ignores it.
3) Put some white space in your output: e.g. cout << d << ' ' so your numbers are separated.
4) [Acknowledge vincent_zhang] Consider moving to uint64_t as your data type for a, b, and d. This is a standard type in C++11. It's a 64 bit unsigned integer type; adequate for a large number of terms.
and a small thing, bordering on personal opinion,
5) Use ++c instead of c++ as the former will never run slower as, conceptually at least, post-increment has to take a copy of the original value.
Besides the previous answers,
To better format the output, add white space by changing this
cout << d;
to
cout << d << " ";
You may want to change the type of a, b and d from int to double to prevent overflow.
(If you let FibNum=100 in your code, you should be able to observe overflow, meaning that you are going to get some incorrect numbers toward the end of the sequence.)
Move cin.ignore() out of the loop then you dont need to enter to print all the 10 numbers of Fibonacci series

c++ count down script

#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int num, num2;
num = 33;
do
{
cout <<"\n" <<num-3;
}
while (num >=3);
system("PAUSE");
return EXIT_SUCCESS;
}
I have coded the above but when I run it, it outputs 30 and does not deplete the value to 3.
How can I have the loop do this? I know that num-- would work but that would only deplete the value by one. I'm new to c++ and I am trying to figure these things out.
Thanks! :)
//edit thanks I have it working now with num = num - 3, num-=3 works too
this line:
cout <<"\n" <<num-3;
does not change the value of num. It just outputs the value of num - 3. To actually change the value you need another line, such as:
num -= 3;
Even if you do as suggested and subtract 3 (or whatever) every iteration of your loop, it may not do a whole lot of good. The problem is fairly simple: you're likely updating your variable a lot faster than the output can be printed, so you may easily see a dozen or more values all appear at essentially the same time.
To cure that, you generally want to pause for a short time between iterations, so one value will (probably) be visible before the next is printed. Based on the system("pause");, I'm going to guess you're running Windows, in which case code something like this may be a bit more to your liking:
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
int num = 33;
do
{
cout <<" \r" << (num-=3);
Sleep(100);
}
while (num >=3);
return EXIT_SUCCESS;
}

How to output the Binary value of a variable in C++

I've got a homework assignment in my C++ programming class to write a function that outputs the binary value of a variable's value.
So for example, if I set a value of "a" to a char I should get the binary value of "a" output.
My C++ professor isn't the greatest in the whole world and I'm having trouble getting my code to work using the cryptic examples he gave us. Right now, my code just outputs a binary value of 11111111 no matter what I set it too (unless its NULL then I get 00000000).
Here is my code:
#include <iostream>
#define useavalue 1
using namespace std;
void GiveMeTehBinary(char bin);
int main(){
#ifdef useavalue
char b = 'a';
#else
char b = '\0';
#endif
GiveMeTehBinary(b);
system("pause");
return 0;
}
void GiveMeTehBinary(char bin){
long s;
for (int i = 0; i < 8; i++){
s = bin >> i;
cout << s%2;
}
cout << endl << endl;
}
Thanks a ton in advance guys. You're always extremely helpful :)
Edit: Fixed now - thanks a bunch :D The problem was that I was not storing the value from the bit shift. I've updated the code to its working state above.
The compiler should warn you about certain statements in your code that have no effect1. Consider
bin >> i;
This does nothing, since you don’t store the result of this operation anywhere.
Also, why did you declare tehbinary as an array? All you ever use is one element (the current one). It would be enough to store just the current bit.
Some other things:
NULL must only be used with pointer values. Your usage works but it’s not the intended usage. What you really want is a null character, i.e. '\0'.
Please use real, descriptive names. I vividly remember myself using variables called tehdataz etc. but this really makes the code hard to read and once the initial funny wears off it’s annoying both for you when you try to read your code, and for whoever is grading your code.
Formatting the code properly helps understanding a lot: make the indentation logical and consistent.
1 If you’re using g++, always pass the compiler flags -Wall -Wextra to get useful diagnostics about your code.
Try this:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<8> x('a');
std::cout << x << std::endl;
}
it's actually really simple. to convert from decimal to binary you will need to include #include <bitset> in your program. inside here, it gives you a function that allows you to convert from decimal to binary form. and the function looks like this:
std::cout << std::bitset<8>(0b01000101) << std::endl;
the number 8 in the first argument means the length of the output string. the second argument is the value you want to convert. by the way, you can input a variable in binary form by declaring a 0b in front of the number to write it in binary form. note that to write in binary form is a feature added in c++14 so using any version lower than that won't work. here is the full code if you want to test it out.
#include <iostream>
#include <bitset>
int main()
{
std::cout << std::bitset<8>(0b01000101) << std::endl;
}
note that you don't have to input a binary number to do this.
#include <iostream>
#include <bitset>
int main()
{
std::cout << std::bitset<8>(34) << std::endl;
}
output:
00100010
Why not just check each bit in the unsigned char variable?
unsigned char b=0x80|0x20|0x01; //some test data
int bitbreakout[8];
if(b&0x80) bitbreakout[7]=1;
//repeat above for 0x40, 0x20, etc.
cout << bitbreakout;
There are a TON of ways to optimize this, but this should give you an idea of what do to.
#include <iostream>
using namespace std;
int main(){
int x = 255;
for(int i = numeric_limits<int>::digits; i >=0; i--){
cout << ((x & (1 << i)) >> i);
}
}
it's actually really simple. if you know how to convert decimal to binary, then you can code it easily in c++. in fact I have gone ahead and created a header file that allows you not only to convert from decimal to binary, it can convert from decimal to any number system. here's the code.
#pragma once
#include <string>
char valToChar(const uint32_t val)
{
if (val <= 9)
return 48 + val;
if (val <= 35)
return 65 + val - 10;
return 63;
}
std::string baseConverter(uint32_t num, const uint32_t &base)
{
std::string result;
while (num != 0)
{
result = valToChar(num % base) + result;
num /= base;
}
return result;
}
now, here is how you can use it.
int main()
{
std::cout << baseConverter(2021, 2) << "\n";
}
output:
11111100101