count the # of decimal digits after the radix point - c++

I would like to count the number of decimal digits after the radix point of a floating point number.
The problem obviously raise when the real number doesn't have a representation in the binary system, like 3.5689113.
I am wondering - if for example someone write this real in a source code - if it is possible to get the number 7 namely the number of digits after the radix point
the naive following code for example doesn't work :
int main()
{
double num = 3.5689113;
int count = 0;
num = abs(num);
num = num - int(num);
while ( abs(num) >
0.0000001 )
{
num = num * 10;
count = count + 1;
num = num - int(num);
}
std::cout << count; //48
std::cin.ignore();
}

When something like that doesn't work, you try to print the numbers.
I did so here, and I found you had some floating number precision issues.
I changed the int rounding to ceil rounding and it worked like a charm.
Try putting the ints back and you'll see :)
EDIT: a better strategy than using ceils (which can give the same rounding problems) is to just round the numbers to the nearest integer. You can do that with floor(myNumber+0.5).
Here's the modified code
int main()
{
double num = 3.56891132326923333;
// Limit to 7 digits
num = floor(num*10000000 + 0.5)/10000000;
int count = 0;
num = abs(num);
num = num - floor(num+0.5);
while ( abs(num) >
0.0000001 )
{
cout << num << endl;
num = num * 10;
count = count + 1;
num = num - floor(num+0.5);
}
std::cout << count; //48
std::cin.ignore();
return 0;
}

To prevent the errors introduced by floating point approximation, convert the number to an integer at the earliest possible opportunity and work with that.
double num = 3.5689113;
int count = 7; // a maximum of 7 places
num = abs(num);
int remainder = int(0.5 + 10000000 * (num - int(num)));
while ( remainder % 10 == 0 )
{
remainder = remainder / 10;
--count;
}

For a floating point type T you can get up to std::numeric_limits<T>::digits10 digits restored exactly. Thus, to determine the position of the last non-zero fractional digits you'd use this value as a precision and format the number. To avoid the output using exponent notation you need to set the formatting flags to std::ios_base::fixed and account for the number of non-fractional digits:
std::ostringstream out;
int non_fraction(std::abs(value) < std::numeric_limits<double>::epsilon()
? 1: (1 + std::log(std::abs(value)) / std::log(10)));
out << std::setprecision(std::numeric_limits<double>::digits10 - non_fraction)
<< std::fixed
<< value;
If there is a decimal point, you just need to count the number of digits up to the trailing sequence of zeros.

I would recommend converting to a string, then looping over it and counting how many chars occur after you hit the period. Below is a sample (may need some minor tinkering, been awhile since I've done this in C++);
bool passedRadix = false
int i = 0; // for counting decimals
std::ostringstream strs;
strs << dbl; // dbl is 3.415 or whatever you're counting
std::string str = strs.str();
for(char& c : str) {
if (passedRadix == true)
i++;
if (c == '.')
passedRadix = true;
}

Related

What happend for this pow() function in while loop C++?

I want to find sum of all digit in number power three
such as 14 = 1^3 + 4^3 = 65
I try to code in c++ like this below but it's wrong if I use pow() function.
int number;
int sum = 0;
std::cin >> number;
while(number > 0) {
sum += pow((number%10),3);
number /= 10;
}
std::cout << sum << std::endl;
return 0;
for code above.
if input 153
output should be = 3^3 + 5^3 + 1^3 = 153
but actual output is 152
but this code below it's work very well, Why ? Thank you
int number;
int sum = 0;
std::cin >> number;
while(number > 0) {
sum += (number % 10) * (number % 10) * (number % 10);
number /= 10;
}
std::cout << sum << std::endl;
return 0;
pow(,) is a function that's meant for floating point calculations, so what you get as the primary result is a float. When you assign this result to an int, it is implicitly converted (cast) to an integer, meaning it has to get rid of all the decimals.
So if the primary result happens to be 27.999999998 or something due to finite accuracy of the calculation, this will be converted to the integer 27. This is because float->int cast always rounds towards zero (it was defined that way, presumably due to efficiency reasons).
Function pow is for floating-point numbers and may loose precision when casted back to integer type. Try replacing it with round(pow(number%10,3)).

Having issues in power digit sum in C++

2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?
currently I am working on power digit sum in C++. my program is working properly but it gives inappropriate output.
#include<iostream>
#include<math.h>
using namespace std;
long double calculate(long double n)
{
long double i,j,temp = 0,sum = 0;
while(n != 0)
{
temp = fmod(n,10);
sum = sum + temp;
n = n / 10;
}
return sum;
}
int main()
{
long double i,j,n = 1000,temp = 1,value = 0;
for(i = 1;i <= n;i++)
{
temp = temp * 2;
}
cout << "Multiplication is : " << temp << endl;
value = calculate(temp);
cout.precision(100);
cout << "Sum is : " << value << endl;
return 0;
}
I am getting o/p like this.
Multiplication is : 1.07151e+301
Sum is : 1200.63580205668592182366438692042720504105091094970703125
it shouldn't be in points.it should print in digits.
Representing 2^1000 in binary would take a 1000 bits. Doubles are only 64bits long (long doubles are 80 or 128 bits depending on compiler/architecture). So doubles represent 2^1000 approximately. The input to calculate isn't 2^1000, but rather as close an approximation to it as 80bits allow. That approximation does not contain the lowest digits that calculate would like to sum over.
You can't use any primitive datatype to calculate 2^1000 and later sum of its digits, as its a big number (however, in languages like python and ruby you can do it).
For solving this problem in C/C++, you have to use array (or any other linear data structure like linked list, etc) and apply logic similar to usual pen-paper method of multiplying numbers.
First try to find a bound on number of digits in 2^1000 and then initialize an integer array of size greater than it with all zeroes. Keep the last element to be 1. Now multiply the array (thinking it as a large number such that each digit is in a different cell of the array) with 2, thousand times, taking modulo and carry overs.
Here is the code for above logic:
int ar[303];
int sum =0;
ar[0]=1;
for(int j=1;j<303;j++)
ar[j]=0;
for(int i=1;i<1001;i++)
{
ar[0]=2*ar[0];
for(int k=1;k<303;k++)
ar[k]=2*ar[k] + ar[k-1]/10;
for(int j=0;j<303;j++)
ar[j]=ar[j]%10;
}
for(int i=0;i<303;i++)
sum = sum + ar[i];
cout<<sum;
Hope it helps.
The reason why you are getting your sum with decimal points is because you are dividing a double by 10. This will not result in a clean integer unless the doubles last digit before the decimal point is a zero.
example:
376 / 10 = 37.6
370 / 10 = 37
To solve this change this in your code on line 12:
n = (n-temp)/10;
This will cut the float numbers from your sum at least.
finally i have solved my problem.
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
long double calculate(string n)
{
long double i,j,temp = 0,sum = 0;
for (i = 0;i < n.length();i++)
{
if(n[i] == '.')
{
break;
}
sum = sum + (n[i] - 48);
}
return sum;
}
int main()
{
long double i,j,n = 1000,temp = 1,value = 0;
string str;
temp = pow(2,n);
cout << "Power is : " << temp << endl;
str = to_string(temp);
cout << str << endl;
value = calculate(str);
cout.precision(100);
cout << "Sum is : " << value << endl;
return 0;
}

putting ints into an array c++

this is a super simple problem but it's late and I cant figure out for the life of me why this function doesnt work. I want it to print 1234, but instead it prints 123121. can someone explain what's going on and how to fix it? thanks
#include <iostream>
const int size = 20;
void set_int( int num )
{
int digits[size];
for ( int i = size - 1; i >= 0; i-- )
{
digits[i] = num % 10;
num /= 10;
if ( num != 0 )
std::cout << num;
}
}
int main()
{
set_int( 1234 );
return 0;
}
Well you are outputting the number instead of the digit.
Try changing like,
cout << digits[i]
Further clarification :
On the first run of the loop your num will be 1234 / 10 = 123
Next run your number will be 123 / 10 = 12
Next is going to be 1
You are outputing num, so you get 123121 .
There are several things wrong with that code.
Firstly, the definition
int digits[size];
is a variable length array, which is valid C (since the 1999 C standard) but is not valid C++. Unfortunately, some C++ compilers support such things as an extension.
Second, even if we assume that definition is valid, your code is essentially stating that you need an array with 1234 elements to hold integral values corresponding to four digits (1,2,3, and 4).
As MichaelCMS has described, your code is outputting something other than the digits too. A value of 1234 has 4 digits, so you would need to loop a total of 4 times to find all digits (if doing it right). You would not need to loop 1234 times.
MichaelCMS explained correctly, why you have such output. There are mistakes in your function. I wrote another one.
You can use next code, which helps to find digits of number.
#include <iostream>
int FindNumberOfDigits(int number);
void SplitNumberIntoDigits(int number);
// Splits number into digits.
// Works with not big numbers.
void SplitNumberIntoDigits(int number)
{
int size = FindNumberOfDigits(number);
int * digits = new int[size];
int divider = 0;
int degree = 0;
for(int digit = size; digit > 0; digit --)
{
// Find degree of divider
degree = digit;
// Find divider for each digit of number.
// For 1234 it will be 1000. For 234 it will be 100.
divider = pow(10, degree - 1);
// We use "abs" to get digits without "-".
// For example, when -1234 / 1000, you get -1.
digits[digit] = abs(number / divider);
// Cut number to find remaining digits.
number %= divider;
std::cout << digits[digit];
}
std::cout << std::endl;
}
// If number = 0, number of digits will be 1.
// Else returns number of digits.
int FindNumberOfDigits(int number)
{
int digitsNumber = 0;
if (number)
{
// calculates number of digits
while (number / 10)
{
number /= 10;
digitsNumber ++;
}
}
digitsNumber += 1;
return digitsNumber;
}
int _tmain(int argc, _TCHAR* argv[])
{
SplitNumberIntoDigits(1234);
SplitNumberIntoDigits(0);
SplitNumberIntoDigits(1);
SplitNumberIntoDigits(-1234);
SplitNumberIntoDigits(1234567890);
return 0;
}
As a result this code can help you to find digits of not big numbers. It works with positive, negative numbers and zero.

convert decimal to 32 bit binary?

convert a positive integer number in C++ (0 to 2,147,483,647) to a 32 bit binary and display.
I want do it in traditional "mathematical" way (rather than use bitset or use vector *.pushback* or recursive function or some thing special in C++...), (one reason is so that you can implement it in different languages, well maybe)
So I go ahead and implement a simple program like this:
#include <iostream>
using namespace std;
int main()
{
int dec,rem,i=1,sum=0;
cout << "Enter the decimal to be converted: ";
cin>>dec;
do
{
rem=dec%2;
sum=sum + (i*rem);
dec=dec/2;
i=i*10;
} while(dec>0);
cout <<"The binary of the given number is: " << sum << endl;
system("pause");
return 0;
}
Problem is when you input a large number such as 9999, result will be a negative or some weird number because sum is integer and it can't handle more than its max range, so you know that a 32 bit binary will have 32 digits so is it too big for any number type in C++?. Any suggestions here and about display 32 bit number as question required?
What you get in sum as a result is hardly usable for anything but printing. It's a decimal number which just looks like a binary.
If the decimal-binary conversion is not an end in itself, note that numbers in computer memory are already represented in binary (and it's not the property of C++), and the only thing you need is a way to print it. One of the possible ways is as follows:
int size = 0;
for (int tmp = dec; tmp; tmp >>= 1)
size++;
for (int i = size - 1; i >= 0; --i)
cout << ((dec >> i) & 1);
Another variant using a character array:
char repr[33] = { 0 };
int size = 0;
for (int tmp = dec; tmp; tmp >>= 1)
size++;
for (int i = 0; i < size; ++i)
repr[i] = ((dec >> (size - i - 1)) & 1) ? '1' : '0';
cout << repr << endl;
Note that both variants don't work if dec is negative.
You have a number and want its binary representation, i.e, a string. So, use a string, not an numeric type, to store your result.
Using a for-loop, and a predefined array of zero-chars:
#include <iostream>
using namespace std;
int main()
{
int dec;
cout << "Enter the decimal to be converted: ";
cin >> dec;
char bin32[] = "00000000000000000000000000000000";
for (int pos = 31; pos >= 0; --pos)
{
if (dec % 2)
bin32[pos] = '1';
dec /= 2;
}
cout << "The binary of the given number is: " << bin32 << endl;
}
For performance reasons, you may prematurely suspend the for loop:
for (int pos = 31; pos >= 0 && dec; --pos)
Note, that in C++, you can treat an integer as a boolean - everything != 0 is considered true.
You could use an unsigned integer type. However, even with a larger type you will eventually run out of space to store binary representations. You'd probably be better off storing them in a string.
As others have pointed out, you need to generate the results in a
string. The classic way to do this (which works for any base between 2 and 36) is:
std::string
toString( unsigned n, int precision, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string retval;
while ( n != 0 ) {
retval += digits[ n % base ];
n /= base;
}
while ( retval.size() < precision ) {
retval += ' ';
}
std::reverse( retval.begin(), retval.end() );
return retval;
}
You can then display it.
Recursion. In pseudocode:
function toBinary(integer num)
if (num < 2)
then
print(num)
else
toBinary(num DIV 2)
print(num MOD 2)
endif
endfunction
This does not handle leading zeros or negative numbers. The recursion stack is used to reverse the binary bits into the standard order.
Just write:
long int dec,rem,i=1,sum=0
Instead of:
int dec,rem,i=1,sum=0;
That should solve the problem.

How to check number?

Could anyone please tell me how to check what number I've got from a * b? Which is I would like to know every part of this number so for example if the result from this expression would be 25 I would like to know that first digit is two and second digit is five.
perhaps a little overkill... but even works with doubles
#include <sstream>
#include <iostream>
int main()
{
double a = 5.2;
double b = 7;
double z = a*b;
std::stringstream s;
s << z;
for (int i = 0; i < s.str().length(); i++)
std::cout << i << ": " << s.str()[i] << std::endl;
return 0;
}
a mod 10 == last digit of a
a / 10 == a without its last digit
So, for 25:
25 % 10 == 5 => 5 is the last digit of 25
25 / 10 == 2
2 % 10 == 2 => 2 is the first digit of 25
You can use these in a while loop to get each digit.
while (num > 0)
{
digit = num % 10;
// digit is now the current digit, counting from the right towards the left.
num /= 10;
}
int val = res;
while( val > 0 )
{
std::cout << val % 10 << endl;
val /= 10;
}
You have to get the result of the integer division by the appropriate power of ten.
int exp = std::floor( std::log10( num ) );
int first_digit = num / int( std::pow( 10.0, exp ) );
This is an (inefficient) way to get the first digit directly. It would be better to iterate starting from the last.
char str[30];
sprintf(str,"%d",a*b);
int ndigits = strlen(str);
There you have all digits of your value in the string, and the number of digits in ndigits.
e.g. if a*b = 25 you get
ndigits==2
str[ndigits-1]=='5'
str[ndigits-2]=='2'
What do you want this for?
There's probably an underlying misunderstanding here. The result of the multiplication will most likely be 0x00000019. (Number of leading zeroes will differ). The second step, converting it to canonical decimal will yield "25".
It's important to realize that computers, unlike normal humans, don't do their math in decimal but in binary. Hence, if you want to check a property like "last decimal digit of a number", it's not directly available to them.
Just remember, that e.g. 2101 is basically just 2*10^3 + 1*10^2 + 0*10^1 + 1*10^0.