I want to print the amount of numbers that are within the range of two numbers (those two numbers included).
I have created this simple code:
#include <iostream>
int main(int argc, char *argv[]) {
int one = -5;
int two = 5;
unsigned int count = 0;
int min = std::min(one, two);
int max = std::max(one, two);
while (min <= max) {
count++;
min++;
}
std::cout << count << std::endl;
return 0;
}
In this example I use -5 to 5 and it correctly prints 11.
How can I improve this algorithm so that it works without problem with numbers ranging from for example -1 billion to 1 billion?
Or is the code fine as it stands?
The number of numbers in that range is simply their difference + 1:
count = max - min + 1;
Or, without evaluating which is the max and which the min, use the absolute value of the difference
count = std::abs(one - two) + 1;
Maybe I missed something, but
#include <iostream>
int main(int argc, char *argv[]) {
int one = -5;
int two = 5;
unsigned int count = std::abs(one-two)+1;
std::cout << count << std::endl;
return 0;
}
should do exactly what you want?
This will give 11 for -5 and 5, which is in fact the count of numbers betweeen -5 and 5, including both. If you want it to print 10, as you said in your quetion you have to remove the +1.
You need to use an integral type that can contain such range of numbers. At present the greatest fundamental signed integral type in C++ is long long int You can get the range of numbers it can store by using expressions
std::numeric_limits<long long int>::min() and std::numeric_limits<long long int>::max()
structure std::numeric_limits is defined in header <limits>
For example
#include <iostream>
#include <limits>
int main()
{
std::cout << std::numeric_limits<long long int>::min() << " - "
<< std::numeric_limits<long long int>::max() << std::endl;
}
Also it would be better if the program would ask the user to enter the two numbers. For big ranges it is better to use a simple arithmetic expression to get the counter instead of using the loop.
Related
I have a vector of numbers (floats), representing everything after the second of some time stamp. They have varying lengths. It looks something like this:
4456
485926
346
...
Representing 0.4456, 0.485926, and 0.346 seconds, respectively. I need to convert each of these to milliseconds, however I can’t simply multiply each by some constant since they’re all of different lengths. I’m fine with loosing accuracy, I just need the first 3 digits (the millisecond bit). How can this be done?
Try this:
#include <iostream>
#include <string>
using namespace std;
int getFirstThreeDigits(int number){
return stoi(to_string(number).substr(0,3));
}
int main()
{
float values[] = {4456, 485926, 346};
int arrLength = (sizeof(values)/sizeof(*values));
for( int i = 0 ; i < arrLength ; i++){
cout << getFirstThreeDigits(values[i]) << endl;
}
}
I'm assuming here that the integral portion of the float represents a subsecond value, so that 1234f is actually 0.1234 seconds. That seems to be what your question states.
If that's the case, it seems to me you can just continuously divide the value by ten until you get something less than one. Then multiply it by one thousand and round. That would go something like:
#include <iostream>
int millis(float value) {
if (value < 0) return -millis(-value);
//while (value >= 1000f) value /= 1000f;
while (value >= 1.0f) value /= 10.f;
return static_cast<int>(value * 1000 + .5f);
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {
float f= atof(argv[i]);
std::cout << " " << f << " -> " << millis(f) << "\n";
}
}
I've also put in a special case to handle negative number and a (commented-out, optional) optimisation to more quickly get down to sub-one for larger numbers.
A transcript follows with your example values:
pax> ./testprog 4456 485926 346
4456 -> 446
485926 -> 486
346 -> 346
If instead the values are already sub-second floats and you just want the number of milli-seconds, you do the same thing but without the initial divisions:
int millis(float value) {
if (value < 0) return -millis(-value);
return static_cast<int>(value * 1000 + .5f);
}
Using "(int)log10 + 1" is an easy way to get the number of integer digits
auto x = 485926;
auto len = (int)std::log10(x) + 1;
https://godbolt.org/z/v1jz7P
I want to make a simple program that will take number of bits from the input and as an output show binary numbers, written on given bits (example: I type 3: it shows 000, 001, 010, 011, 100, 101, 110, 111).
The only problem I get is in the second for-loop, when I try to assign variable in bitset<bits>, but it wants constant number.
If you could help me find the solution I would be really greatful.
Here's the code:
#include <iostream>
#include <bitset>
#include <cmath>
using namespace std;
int main() {
int maximum_value = 0,x_temp=10;
//cin >> x_temp;
int const bits = x_temp;
for (int i = 1; i <= bits; i++) {
maximum_value += pow(2, bits - i);
}
for (int i = maximum_value; i >= 0; i--)
cout << bitset<bits>(maximum_value - i) << endl;
return 0;
}
A numeric ("non-type", as C++ calls it) template parameter must be a compile-time constant, so you cannot use a user-supplied number. Use a large constant number (e.g. 64) instead. You need another integer that will limit your output:
int x_temp = 10;
cin >> x_temp;
int const bits = 64;
...
Here 64 is some sort of a maximal value you can use, because bitset has a constructor with an unsigned long long argument, which has 64 bits (at least; may be more).
However, if you use int for your intermediate calculations, your code supports a maximum of 14 bits reliably (without overflow). If you want to support more than 14 bits (e.g. 64), use a larger type, like uint32_t or uint64_t.
A problem with holding more bits than needed is that the additional bits will be displayed. To cut them out, use substr:
cout << bitset<64>(...).to_string().substr(64 - x_temp);
Here to_string converts it to string with 64 characters, and substr cuts the last characters, whose number is x_temp.
You have to define const int bits=10; as a global constant :
#include <iostream>
#include <math.h>
#include <bitset>
using namespace std;
const unsigned bits=10;
int main() {
int maximum_value = 0,x_temp=10;
for (int i = 1; i <= bits; i++) {
maximum_value += pow(2, bits - i);
}
for (int i = maximum_value; i >= 0; i--)
cout << bitset<bits>(maximum_value - i) << endl;
return 0;
}
I have written a C++ program to find all the automorphic numbers (numbers which are repeated in the final digits of their squares such as 5x5=25, 76x76=5776) from 1 to 111,111. The program runs fine except that it fails to give 90625 and 109376. The code is as follows:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
long int square;
int a, sum = 0, result, b;
for (int i = 1; i < 111111; i++) {
result = 1;
b = i;
while (b > 0){
b = b / 10;
result = result * 10;
}
square = i * i;
a = square % result;
if(i == a){
sum = sum + i;
cout << i << endl;
}
}
cout << sum << endl;
return 0;
}
Long int has only 4 bytes
long 4 bytes -2,147,483,648 to 2,147,483,647
unsigned long 4 bytes 0 to 4,294,967,295
The square of 90625 and 109376 are 8,212,890,625 and 11,963,109,376 respectively. So as the values overflow, you won't be able to produce those two values in long int limit. You can use integer type long long.
long long 8 bytes –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned long long 8 bytes 0 to 18,446,744,073,709,551,615
And if you want to use bigger numbers you can handle them using Arrays or let libraries like GMP to handle larger numbers.
I try
long long int l = 42343254325322343224;
but to no avail. Why does it tell me, "integer constant is too long." I am using the long long int type which should be able to hold more than 19 digits. Am I doing something wrong here or is there a special secret I do not know of just yet?
Because it's more, on my x86_64 system, of 2^64
// 42343254325322343224
// maximum for 8 byte long long int (2^64) 18446744073709551616
// (2^64-1 maximum unsigned representable)
std::cout << sizeof(long long int); // 8
you shouldn't confuse the number of digits with the number of bits necessary to represent a number
Take a look at Boost.Multiprecision at Boost.Multiprecision
It defines templates and classes to handle larger numbers.
Here is the example from the Boost tutorial:
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int128_t v = 1;
// Do some fixed precision arithmetic:
for(unsigned i = 1; i <= 20; ++i)
v *= i;
std::cout << v << std::endl; // prints 20!
// Repeat at arbitrary precision:
cpp_int u = 1;
for(unsigned i = 1; i <= 100; ++i)
u *= i;
std::cout << u << std::endl; // prints 100!
It seems that the value of the integer literal exceeds the acceptable value for type long long int
Try the following program that to determine maximum values of types long long int and unsigned long long int
#include <iostream>
#include <limits>
int main()
{
std::cout << std::numeric_limits<long long int>::max() << std::endl;
std::cout << std::numeric_limits<unsigned long long int>::max() << std::endl;
return 0;
}
I have gotten the following results at www.ideone.com
9223372036854775807
18446744073709551615
You can compare it with the value you specified
42343254325322343224
Take into account that in general case there is no need to specify suffix ll for a integer decimal literal that is so big that can be stored only in type long long int The compiler itself will determine the most appropriate type ( int or long int or long long int ) for the integral decimal literal.
How do I detect the length of an integer? In case I had le: int test(234567545);
How do I know how long the int is? Like telling me there is 9 numbers inside it???
*I have tried:**
char buffer_length[100];
// assign directly to a string.
sprintf(buffer_length, "%d\n", 234567545);
string sf = buffer_length;
cout <<sf.length()-1 << endl;
But there must be a simpler way of doing it or more clean...
How about division:
int length = 1;
int x = 234567545;
while ( x /= 10 )
length++;
or use the log10 method from <math.h>.
Note that log10 returns a double, so you'll have to adjust the result.
Make a function :
int count_numbers ( int num) {
int count =0;
while (num !=0) {
count++;
num/=10;
}
return count;
}
Nobody seems to have mentioned converting it to a string, and then getting the length. Not the most performant, but it definitely does it in one line of code :)
int num = -123456;
int len = to_string(abs(num)).length();
cout << "LENGTH of " << num << " is " << len << endl;
// prints "LENGTH of 123456 is 6"
You can use stringstream for this as shown below
stringstream ss;
int i = 234567545;
ss << i;
cout << ss.str().size() << endl;
if "i" is the integer, then
int len ;
char buf[33] ;
itoa (i, buf, 10) ; // or maybe 16 if you want base-16 ?
len = strlen(buf) ;
if(i < 0)
len-- ; // maybe if you don't want to include "-" in length ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i=2384995;
char buf[100];
itoa(i, buf, 10); // 10 is the base decimal
printf("Lenght: %d\n", strlen(buf));
return 0;
}
Beware that itoa is not a standard function, even if it is supported by many compilers.
len=1+floor(log10(n));//c++ code lib (cmath)
looking across the internet it's common to make the mistake of initializing the counter variable to 0 and then entering a pre-condition loop testing for as long as the count does not equal 0. a do-while loop is perfect to avoid this.
unsigned udc(unsigned u) //unsigned digit count
{
unsigned c = 0;
do
++c;
while ((u /= 10) != 0);
return c;
}
it's probably cheaper to test whether u is less than 10 to avoid the uneccessary division, increment, and cmp instructions for cases where u < 10.
but while on that subject, optimization, you could simply test u against constant powers of ten.
unsigned udc(unsigned u) //unsigned digit count
{
if (u < 10) return 1;
if (u < 100) return 2;
if (u < 1000) return 3;
//...
return 0; //number was not supported
}
which saves you 3 instructions per digit, but is less adaptable for different radixes inaddition to being not as attractive, and tedious to write by hand, in which case you'd rather write a routine to write the routine before inserting it into your program. because C only supports very finite numbers, 64bit,32bit,16bit,8bit, you could simply limit yourself to the maximum when generating the routine to benefit all sizes.
to account for negative numbers, you'd simply negate u if u < 0 before counting the number of digits. of course first making the routine support signed numbers.
if you know that u < 1000,
it's probably easier to just write, instead of writing the routine.
if (u > 99) len = 3;
else
if (u > 9) len = 2;
else len = 1;
Here are a few different C++ implementations* of a function named digits() which takes a size_t as argument and returns its number of digits. If your number is negative, you are going to have to pass its absolute value to the function in order for it to work properly:
The While Loop
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
The Exhaustive Optimization Technique
int digits(size_t i) {
if (i > 9999999999999999999ull) return 20;
if (i > 999999999999999999ull) return 19;
if (i > 99999999999999999ull) return 18;
if (i > 9999999999999999ull) return 17;
if (i > 999999999999999ull) return 16;
if (i > 99999999999999ull) return 15;
if (i > 9999999999999ull) return 14;
if (i > 999999999999ull) return 13;
if (i > 99999999999ull) return 12;
if (i > 9999999999ull) return 11;
if (i > 999999999ull) return 10;
if (i > 99999999ull) return 9;
if (i > 9999999ull) return 8;
if (i > 999999ull) return 7;
if (i > 99999ull) return 6;
if (i > 9999ull) return 5;
if (i > 999ull) return 4;
if (i > 99ull) return 3;
if (i > 9ull) return 2;
return 1;
}
The Recursive Way
int digits(size_t i) { return i < 10 ? 1 : 1 + digits(i / 10); }
Using snprintf() as a Character Counter
⚠ Requires #include <stdio.h> and may incur a significant performance penalty compared to other solutions. This method capitalizes on the fact that snprintf() counts the characters it discards when the buffer is full. Therefore, with the right arguments and format specifiers, we can force snprintf() to give us the number of digits of any size_t.
int digits(size_t i) { return snprintf (NULL, 0, "%llu", i); }
The Logarithmic Way
⚠ Requires #include <cmath> and is unreliable for unsigned integers with more than 14 digits.
// WARNING! There is a silent implicit conversion precision loss that happens
// when we pass a large int to log10() which expects a double as argument.
int digits(size_t i) { return !i? 1 : 1 + log10(i); }
Driver Program
You can use this program to test any function that takes a size_t as argument and returns its number of digits. Just replace the definition of the function digits() in the following code:
#include <iostream>
#include <stdio.h>
#include <cmath>
using std::cout;
// REPLACE this function definition with the one you want to test.
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
// driver code
int main ()
{
const int max = digits(-1ull);
size_t i = 0;
int d;
do {
d = digits(i);
cout << i << " has " << d << " digits." << '\n';
i = d < max ? (!i ? 9 : 10 * i - 1) : -1;
cout << i << " has " << digits(i) << " digits." << '\n';
} while (++i);
}
* Everything was tested on a Windows 10 (64-bit) machine using GCC 12.2.0 in Visual Studio Code .
As long as you are mixing C stdio and C++ iostream, you can use the snprintf NULL 0 trick to get the number of digits in the integer representation of the number. Specifically, per man 3 printf If the string exceeds the size parameter provided and is truncated snprintf() will return
... the number of characters (excluding the terminating null byte)
which would have been written to the final string if enough space
had been available.
This allows snprintf() to be called with the str parameter NULL and the size parameter 0, e.g.
int ndigits = snprintf (NULL, 0, "%d", 234567545)
In your case where you simply wish to output the number of digits required for the representation, you can simply output the return, e.g.
#include <iostream>
#include <cstdio>
int main() {
std::cout << "234567545 is " << snprintf (NULL, 0, "%d", 234567545) <<
" characters\n";
}
Example Use/Output
$ ./bin/snprintf_trick
234567545 is 9 characters
note: the downside to using the snprintf() trick is that you must provide the conversion specifier which will limit the number of digits representable. E.g "%d" will limit to int values while "%lld" would allow space for long long values. The C++ approach using std::stringstream while still limited to numeric conversion using the << operator handles the different integer types without manually specifying the conversion. Something to consider.
second note: you shouldn't dangle the "\n" of the end of your sprintf() conversion. Add the new line as part of your output and you don't have to subtract 1 from the length...