Count the number of digits in a given number [duplicate] - c++

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 11 months ago.
Hello I am trying to count the number of digits in a given double. I am encountering an infinite loop doing so. I tried to isolate each while statement and it works fine but when I combine them I am having an infinite loop on a the second while condition. here's the code
#include <iostream>
using namespace std;
int main()
{
//Counting digits of a number
double N, M, b;
int i, j, a;
cout << "This program will count how many digits the given whole number has.\n\n";
cout << "Please enter the Number: "; // N = 123.567 Digits should be = 6
cin >> N;
a = (int)N;
M = N - a;
b = M - int(M);
j = 0;
if (a == 0 && b == 0)
cout << "You have entered number 0.";
else
{
i = 0;
j = 0;
while (a > 0) //for the integer (whole number) part of the number
{
a /= 10;
i++;
}
while (b != 0) //for the fractional part of the number
{
j++;
M *= 10;
b = M - int(M);
}
cout << "Display i: " << i << endl; // i = number of whole number digits
cout << "Display j: " << j << endl; // j = number of fractional digits
}
system("pause > 0");
}

As a double stores fraction parts to a more significant extent, you cannot count digits in a double in this way.
Instead,
Accept the number as a string.
Convert it to double using stod()
Step2 is to make sure the user has entered the number as if it's other than the number it'll give an exception.
Count digits in the string.
Here is what it will look like
#include<iostream>
#include<string.h>
using namespace std;
int main(){
string str = "";
cin>>str;
int counter =0;
try{
double d = stod(str);
for(int i=0;i<str.length();i++){
if(str.at(i) >= '0' && str.at(i) <= '9')
counter++;
}
cout<<counter;
}
catch(...){
cout<<"Please enter only numbers";
}
return 0;
}
I have used catch which is general, meaning it will catch all exceptions. You can use specific exception too.

Using a floating point type at any point in this analysis is not the correct thing to do. That's because (like an integral type) they can only store a subset of the real number set.
A good approach here would be to read the input as a string, check that it is a plausible number (e.g. does it contain only one decimal separator)? Write something clever to trim any zeros after the decimal separator and leading zeros before the number, allow for a negative sign, then count the digits.

Related

How to reverse my input including the negative

This is my code that I have currently but it always outputs 0 I'm trying to get it to output the reverse of the input including the negative for example -123425 will be 524321-:
#include<iostream>
using namespace std;
int main() {
int number;
bool negative;
cout << "Enter an integer: ";
cin >> number;
while (number != 0) {
number % 10;
number /= 10;
}
if (number < 0) {
negative = true;
number = -number;
cout << number << "-";
}
else {
negative = false;
}
cout << number << endl;
return EXIT_SUCCESS;
}
You could convert the input to a std::string, then reverse its content with std::reverse.
#include <algorithm> // reverse
#include <cstdlib> // EXIT_SUCCESS
#include <iostream> // cin, cout, endl
#include <string> // string, to_string
using namespace std;
int main()
{
cout << "Enter an integer: ";
int number;
cin >> number;
auto str = to_string(number);
reverse(str.begin(), str.end());
cout << str << endl;
return EXIT_SUCCESS;
}
Reading to an int first - and not to a std::string - makes sure that we parse a valid integer from the input. Converting it to a std::string allow us to reverse it. This let us feed inputs like -042 and -0 to the program, and get 24- and 0 as a result, not 240- and 0-.
After the first loop
while (number != 0) {
number % 10;
number /= 10;
}
the variable number is equal to 0.
So the following if statement
if (number < 0) {
negative = true;
number = -number;
cout << number << "-";
}
else {
negative = false;
}
does not make sense.
Pay attention to that it can happen such a way that a reversed number can not fit in an object of the type int. So for the result number you should select a larger integer type.
Here is a demonstrative program that shows how the assignment can be done.
#include <iostream>
int main()
{
std::cout << "Enter an integer: ";
int n = 0;
std::cin >> n;
bool negative = n < 0;
const int Base = 10;
long long int result = 0;
do
{
int digit = n % Base;
if ( digit < 0 ) digit = -digit;
result = Base * result + digit;
} while ( n /= Base );
std::cout << result;
if ( negative ) std::cout << '-';
std::cout << '\n';
return 0;
}
Its output might look like
Enter an integer: 123456789
987654321-
I think trying to visualize the process of your program is a great way to see if your solution is doing what you expect it to. To this end, let's assume that our number is going to be 12345. The code says that while this is not equal to 0, we will do number % 10 and then number /= 10. So if we have 12345, then:
number % 10 --> 12345 % 10 --> 5 is not assigned to any value, so no change is made. This will be true during each iteration of the while loop, except for different values of number along the way.
number /= 10 --> 12345 /= 10 --> 1234
number /= 10 --> 1234 /= 10 --> 123
number /= 10 --> 123 /= 10 --> 12
number /= 10 --> 12 /= 10 --> 1
number /= 10 --> 1 /= 10 --> 0 (because of integer division)
Now that number == 0 is true, we proceed to the if/else block, and since number < 0 is false we will always proceed to the else block and then finish with the cout statement. Note that the while loop will require number == 0 be true to exit, so this program will always output 0.
To work around this, you will likely either need to create a separate number where you can store the final digits as you loop through, giving them the correct weight by multiplying them by powers of 10 (similar to what you are hoping to do), or cast your number to a string and print each index of the string in reverse using a loop.
Quite simple:
int reverse(int n){
int k = abs(n); //removes the negative signal
while(k > 0){
cout<<k % 10; //prints the last character of the number
k /= 10; //cuts off the last character of the number
}
if(n < 0) cout<<"-"; //prints the - in the end if the number is initially negative
cout<<endl;
}
int main(){
int n = -1030; //number you want to reverse
reverse(n);
}
If you don't want to use String or have to use int, here is the solution.
You want to check the negativity before you make changes to the number, otherwise the number would be 0 when it exit the while loop. Also, the modulus would be negative if your number is negative.
number % 10 only takes the modulus of the number, so you want to cout this instead of just leaving it there.
The last line you have cout << number << endl; will cout 0 since number has to be 0 to exit the while loop.
if(number < 0) {
number = -number;
negative = true;
}
while (number != 0) {
cout << number % 10;
number /= 10;
}
if (negative) {
cout << "-"<< endl;
}
EDIT: With a broader assumption of the input taking all int type values instead of the reversed integer being a valid int type. Here is a modified solution.
if(number < 0) {
negative = true;
}
while (number != 0) {
cout << abs(number % 10);
number /= 10;
}
if (negative) {
cout << "-"<< endl;
}
using namespace std;
int main()
{
int number,flag=1;
long long int revnum=0;
bool negative;
cout << "Enter an integer: ";
cin >> number;
if(number<0)
{ negative=true;
}
while (number > 0) {
revnum=revnum*10+number %10;
number /= 10;
}
if (negative)
{ revnum=(-revnum);
cout << revnum << '-'<<endl;
}
else
{ cout<<revnum<<endl;
}
return 0;
}
A few changes I did -
checking the number whether it's negative or positive
if negative converting it to positive
3.reversing the number with the help of a new variable revnum
4.and the printing it according to the requirement
To reverse the num-
revnum=revnum*10 + number%10
then num=num/10
like let's try to visualize
1.take a number for example like 342
2.for 1st step revnum=0 so revnum*10=0 and num%10=2 , so revnum will be 2
and the number now is num/10 so 34
4.next now rev = 2 the rev*10=20 and num%10=4 then rev*10 + num/10 =24
5.finally we get 243
Hope it helps :)
edit:-
just a small edit to solve the problem of the overflow of int , made revnum as long long int.

Getting wrong results after simple multiplication - C++

So, what needs to be done is: enter a real number and print the sum of its first 4 digits after the decimal point. E.g.: I enter 5.1010. I get to the point where I need to multiply 0.1010 by 10000 so it can become an integer, but the result I'm getting is 1009 instead of 1010 and everything falls apart after that.
I'd be forever thankful if someone can explain to me why does that happen.
#include<iostream>
using namespace std;
int main()
{
double n;
cout<<"Enter a positive real number: ";
do
{
cin>>n;
if(n<=0) cout<<"The number must be positive, enter again: ";
}while(n<=0);
//storing the fractional part in a var
int y=n;
double fr=n-y;
//turning the fractional part into an integer
int fr_int=fr*10000;
cout<<fr_int<<endl;
//storing each of the digits in a var
int a=fr_int/1000;
int b=fr_int/100%10;
int c=fr_int/10%10;
int d=fr_int%10;
cout<<"The sum of the first 4 digits is: " << a+b+c+d;
return 0;
}
You could simply change the code as follows, then it should be working.
n *= 10000;
int Integer = n;
int i = 4;
int sum = 0;
while(i--)
{
sum += (Integer%10);
Integer /= 10;
}
std::cout << "The sum of the first 4 digits is: " << sum;
Here is the output: https://www.ideone.com/PevZgn
Update:A generalized soln would be using std::string. However, would be great if the code is capable of handling exceptions in the case of non-numeric has been submitted by the user.
#include <iostream>
#include <string>
int main()
{
std::string Number;
double tempNum = 0.0;
std::cout << "Enter a positive real number: ";
do
{
std::cin >> Number;
tempNum = std::stof(Number);
if(tempNum <= 0)
std::cout << "The number must be positive, enter again: ";
}while(tempNum <= 0);
bool Okay = false;
int sum = 0;
int i = 4;
for(const auto& it: Number)
{
if(Okay && i > 0)
{
sum += static_cast<int>(it - '0');
--i;
}
if(it == '.') Okay = true;
}
std::cout << "The sum of the first 4 digits is: " << sum;
return 0;
}
I think you should add 0.5 before casting because the compile will always truncate the number.
In C++11 you can use std::round.
Floating points and doubles in C++ aren't able to represent all decimal numbers accurately. In particular, 0.1, it cannot represent faithfully.
If you must be guaranteed that you get accurate results, you should either use fixed point math or a bignumber library.

Why does the following code crash when I input a 12 digit number? [duplicate]

This question already has answers here:
cin >> fails with bigger numbers but works with smaller ones?
(4 answers)
Closed 5 years ago.
I have been following a course about algorithms on Coursera and I tried to put what I learned into code. This is supposed to be a "divide & conquer" algorithm and I hope that part is alright. I have a problem I encountered just messing around with it: everything works fine until I input a 12 digit number into the program. When I do that, it just ends the cin and outputs all the previous numbers sorted (blank space if no numbers are before). If you could, please tell me what's wrong if you spot the mistake. This is my code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
// setup global variable for the number of inversions needed
int inversions = 0;
// function to merge 2 sublists into 1 sorted list
vector<int> Merge_and_Count(vector<int>& split_lo, vector<int>& split_hi) {
// setup output variable -> merged, sorted list of the 2 input sublists
vector<int> out;
int l = 0;
int m = 0;
// loop through all the elements of the 2 sublists
for (size_t k = 0; k < split_lo.size() + split_hi.size(); k++) {
// check if we reached the end of the first sublist
if (l < split_lo.size()) {
// check if we reached the end of the second sublist
if (m < split_hi.size()) {
// check which element is smaller and sort accordingly
if (split_lo[l] < split_hi[m]) {
out.push_back(split_lo[l]);
l++;
}
else if (split_hi[m] < split_lo[l]) {
out.push_back(split_hi[m]);
m++;
inversions++;
}
}
else {
out.push_back(split_lo[l]);
l++;
inversions++;
}
}
else {
out.push_back(split_hi[m]);
m++;
}
}
return out;
}
// function that loops itself to split input into halves until it reaches the base case (1 element array)
vector<int> MergeSort_and_CountInversions(vector<int>& V) {
// if we reached the base case, terminate the loop and feed the output to the previous loop to be processed
if (V.size() == 1) return V;
// if we didn't reach the base case
else {
// continue halving the sublists
size_t const half_size = V.size() / 2;
vector<int> split_lo(V.begin(), V.begin() + half_size);
vector<int> split_hi(V.begin() + half_size, V.end());
// feed them back into the loop
return Merge_and_Count(MergeSort_and_CountInversions(split_lo), MergeSort_and_CountInversions(split_hi));
}
}
// main function of the app, runs everything
int main()
{
// setup main variables
int input;
vector<int> V;
// get input
cout << "Enter your numbers to be sorted (enter Y when you wish to proceed to the sorting)." << endl;
cout << "Note: do NOT use duplicates (for example, do not input 1 and 1 again)!" << endl;
while (cin >> input)
V.push_back(input);
cout << "\nThe numbers you chose were: " << endl;
for (size_t i = 0; i < V.size(); i++)
cout << V[i] << " ";
// get sorted output
vector<int> sorted = MergeSort_and_CountInversions(V);
cout << "\n\nHere are your numbers sorted: " << endl;
for (size_t j = 0; j < sorted.size(); j++)
cout << sorted[j] << " ";
// show number of inversions that were needed
cout << "\n\nThe number of inversions needed were: " << inversions << endl;
return 0;
}
12 decimal digits is too long to fit into a 32-bit number, which is how int is usually represented. Reading that number using >> therefore fails and cin >> input converts to a false value, which terminates the loop.
See operator >> documentation for details of handling failure modes.
You can get the maximum number of base-10 digits that can be represented by the type using the std::numeric_limits::digits10 constant:
std::cout << std::numeric_limits<int>::digits10 << '\n';
Chances are the maximum number of significant digits for type int is 9, and you try to supply 12 via standard input. The program doesn't crash, the condition of (cin >> input) simply evaluates to false.
12 digits is too much for 32-bit integer, try to use as unsigned long long int, check these limits:
http://www.cplusplus.com/reference/climits/

C-string assignment using for loop

I think this is a relevant topic, while browsing this forum and tutorial I have tweaked my c-string to the proper format(I think) but there's just one topic missing. How can we take an integer, using a for loop, and assign the c-string values from the integer.
I'm just focusing on the integer to binary part right now and I'm sure my number manipulation is solid. However, my prof said we needed to assign the binary values to a c-string. And I'm trying this, it's telling me I'm using a const char and a char* via the compiler. I'm not sure how this is happening, or how to prevent it.
Here's my source code:
//sample integer to binary
#include <iomanip>
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
int main()
{
int num; //the number a user enters
int rem; //the remainder, the 1 and 0 of the binary number
int x; //a variable to store the number after division
char binary[10]; //c-string initialized to 10, perhaps that is too many.
cout << "Enter a number: ";
cin >> num;
for (int i = 0; i < 10; i++)
{
x = num / 2;
cout << x << endl; //this shows that the code is working
rem = num % 2;
cout << num << endl; //this also shows the code is working
char r = (char)rem; //These two lines of code are
strcpy(binary[i], r); //preventing compilation
cout << binary[i] << endl; // this is diagnostic
num = x;
}
cout << "The number " << num << " is " << binary[5] << " in binary.\n";
return 0;
}
Thanks you two, I've been able to make this work (almost).
I'm still getting some unexpected behavior, and I'm not sure how big to initialize the array to, I don't think that it would matter too much, but I don't know exactly how big of numbers the graders use to test.
Anyways, here's the new code:
#include <iomanip>
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
int main()
{
int num; //the number a user enters
int rem; //the remainder, the 1 and 0 of the binary number
int x; //a variable to store the number after division
char binary[5] = {'0', '\0'}; //c-string initialized to 10, perhaps that is too many.
cout << "Enter a number: ";
cin >> num;
for (int i = 0; i < 10; i++)
{
x = num / 2;
//cout << x << endl; //this shows that the code is working
rem = num % 2;
//cout << num << endl; //also shows the code is working
binary[i] = '0' + rem; //not sure what this is doing, but it works.
//cout << binary[i] << endl; // this is diagnostic
num = x;
}
cout << "The number " << num << " is " << binary << " in binary.\n";
return 0;
}
And here's the output:
Enter a number: 5
The number 0 is 1010000000# in binary.
It should show the number, the initial number, and say 101, without the 0's and the # sign.
strcpy is for copying entire NUL-terminated string. If you want to set just one character, you can use =.
binary[i] = r;
However, if you want the line cout << binary[i] to work right, or to treat binary as a C string later, you need to store ASCII digits:
binary[i] = '0' + r;
Don't forget to add a terminating NUL to your string, right now it isn't a C-style string at all.
The arguments to strcpy() are char*, not char. The second argument must point to a null-terminated string, but r is just a single character. To assign a character to an element of an array, do:
binary[i] = r;
But you don't want the binary value of rem, you want the character that represents that binary value. It should be:
char r = '0' + rem;
In order to print binary as a string, you need to give it a null terminator. Since you're putting 10 digits into the string, you need to declare an extra character to hold the terminator, and initialize it with zeroes so it will be terminated properly.
char binary[11] = {0};
And if you want to print the whole string, you shouldn't reference binary[5], you should print the whole array:
cout << "The number " << num << " is " << binary << " in binary.\n";
In addition to problems already pointed out, you get binary digits in the reverse order. You have to count significant digits in your binary representation and reverse characters when you're done.
You didn't initialize the character buffer correctly that's why you are getting garbage in the print out.
As for the buffer size, you need as many characters as there are bits in the integer type you are converting plus one more for the terminating '\0', so for a 32-bit number you need 33 character size buffer. And that's important because if you overrun your buffer, quite nasty things will happen.
And one more note: I assume that numbers you are supposed to convert to a string representation are unsigned, so be explicit about it. Below is a quick and dirty implementation with some minimal error checking:
char *unsigned_to_binstr (unsigned n, char *binary, int buf_len)
{
int i, j;
if (buf_len < 2)
return NULL;
i = 0;
do {
binary[i++] = '0' + n % 2;
n /= 2;
} while (n && i < buf_len);
for (j = 0; j < i / 2; ++j) {
char temp = binary[j];
binary[j] = binary[i-j-1];
binary[i-j-1] = temp;
}
binary[i] = '\0';
return binary;
}
After everyone's comments, and my own research via my textbook I was able to formulate a somewhat working function. However, in the process I began to wonder about the garbage problem, so my solution.. Truncate! I added if clauses (tried to think of a loop representation but didn't get any ideas) and at the end I just use the length provided via if clauses and subtract 1, which should give me the appropriate bit size for the number. Using what basic c++ knowledge we've covered in class this is the solution I came up with, however crude and inefficient it might be!
I want to thank all of you, I couldn't have gotten past the point I was stuck at if it weren't for you!
Here's my rough final revision:
//sample integer to binary
#include <iostream>
using namespace std;
int main()
{
int num; //the number a user enters
int rem; //the remainder, the 1 and 0 of the binary number
int x; //a variable to store the number after division
int l; //length of c-string function
cout << "Enter a number: ";
cin >> num; //user input
if ((num == 1) || (num == 0)) // the following 17 lines of code are to truncate the string size.
l = 2;
if ((num > 1) && (num < 4))
l = 3;
if ((num >= 4) && (num <= 7))
l = 4;
if ((num >= 8) && (num <= 15))
l = 5;
if ((num >= 16) && (num <= 31))
l = 6;
if ((num >= 32) && (num <= 63))
l = 7;
if ((num >= 64) && (num <= 127))
l = 8;
if ((num >= 128) && (num <= 255))
l = 9;
if ((num > 255))
cout << "This number is too large for this string\n"; // I don't think the binary sequence should be larger than 16 bits.
char binary[l]; //c-string initialized to size according to the truncation rules above
for (int i = l - 1; i > 0; i--) //goes in reverse order, as binary counts from bottom to top.
{
x = num / 2;
rem = num % 2;
num = x;
binary[i] = '0' + rem; // added an
}
for (int i = 0; i <= l-1; i++)
{
cout << binary[i];
}
cout << " in binary.\n";
return 0;
}

Large binaries add

this is my first question, so I hope I will not break any of the given rules here on forum. I would like to ask you for help. Im really programming noob, but for homework I have to make a programm in C++ which will add 2 binary numbers. I was able to make it throught converting to a decimal and adding them. I did it bcs I already had some parts for it in my PC. My question is, everything is working fine unless I enter really big binary numbers. Changing data types make difference in results when our school program checks the code. Im not sure waht to change exactly. Thank you in advance. It looks like proble occure when decimal number with "e" has to be converted-
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
using namespace std;
int main ()
{
int k = 0;
int l = 0;
int i = 0;
int j = 0;
double number = 0;
double numberb = 0;
long dec;
string input;
string inputb;
cout << "Enter two binary numbers:" << endl;
cin >> input >> inputb;
if(cin.fail ())
{cout << "Wrong input." << endl;
return 0;
}
for (i = input.length() - 1; i>=0; i-- )
{
if (input[i] != '1' && input[i] != '0')
{
cout << "Wrong input." << endl;
return 0;
}
if (input[i] == '1')
{
number += pow((double)2,(int)j);
}
j++;
}
for (k = inputb.length() - 1; k>=0; k-- )
{
if (inputb[k] != '1' && inputb[k] != '0')
{
cout << "Wrong input." << endl;
return 0;
}
if (inputb[k] == '1')
{
numberb += pow((double)2,(int)l);
}
l++;
}
dec = number+numberb;
vector <double> bin_vector;
long bin_num;
while ( dec >= 1 )
{
bin_num = dec % 2;
dec /= 2;
bin_vector.push_back(bin_num);
}
cout << "Soucet: ";
for ( int i = (double) bin_vector.size() - 1; i >= 0; i-- )
cout << bin_vector[i] << "";
cout << endl;
return 0;
}
Probably your teacher told you that double numbers are great for large numbers. They are, but they have a big disadvantage: They cannot represent large numbers exactly, since they (roughly speaking) only store the first few digits of the number, together with the position of the decimal point, like your pocket calculator shows (for example, 123456E13).
So you should not use double numbers here at all, since you need precise results, no matter how large your numbers are. A better idea is process both strings simultaneously and store the result digit by digit in another string, called result.
By the way: Since double numbers can usually store 53 binary digits precisely, it's good that your tested the program with even more digits.