finding number of trailing zeroes in a number - c++

I wanted to find the number of trailing zeroes in a number, so i made the following code. It worked fine for certain numbers but for bigger numbers it started showing anomaly. Like when i input the number"12345678" it show zero 0`s which is correct but when i input "123456789" it shows one zero, what can be the possible mistake in my code???
#include<iostream>
#include<math.h>
using namespace std;
int main(){
int n = 0;
float s;
cin>>s; //the number to be given as input
for(int j = 0;j <100;j++){
s = s/10;
if(s == floor(s)){
n++;
}else{
break;
}
}
cout<<n<<endl;
return 0;
}

Floating point numbers have a limited precision. Usually, float is a 32-bit number, double is a 64-bit one. Float can store integer numbers precisely if the number is less than or equal to 16777216 (it is 2^24).
So, when 123456789 is read into a float variable, will have a different value, it becomes 123456792. At this point, there is no rationale to count trailing zeros.
Double can store integer numbers precisely if it is less than or equal to 9007199254740992 (2^53).
An unsigned long long int can store integer numbers less than 2^64. If you choose this way, use this condition for checking trailing zero: if (number%10==0)
If you only want to count trailing zeros, and that's all, then use std::string instead. This way you can handle as big numbers as you like.

Related

Casting float to int in C++

int uniquePaths(int m, int n) {
int num = m+n-2;
int den=1;
double ans = 1;
while(den<=m-1) {
ans = ans*(num--)/(den++);
}
cout<<ans;
return (int)ans;
}
The expected answer for m=53, n=4 as input to the above piece of code is 26235 but the code returns 26234. However, the stdout shows 26235.
Could you please help me understand this behavior?
Due to floating-point rounding, your code computes ans to be 26,234.999999999985448084771633148193359375. When it is printed with cout<<ans, the default formatting does not show the full value and rounds it to “26235”. However, when the actual value is converted to int, the result is 26,234.
After setting num to m+n-2, your code is computing num! / ((m-1)!(num-m+1)!), which of course equals num! / ((num-m+1)!(m-1)!). Thus, you can use either m-1 or num-m+1 as the limit. So you can change the while line to these two lines:
int limit = m-1 < num-m+1 ? m-1 : num-m+1;
while(den<=limit) {
and then your code will run to the lower limit, which will avoid dividing ans by factors that are not yet in it. All results will be exact integer results, with no rounding errors, unless you try to calculate a result that exceeds the range of your double format where it is able to represent all integers (up to 253 in the ubiquitous IEEE-754 binary64 format used for double).

Number changing value when assigned to variable?

I have a little problem when assigning a result to a variable, this is happening the first time to me now. I call Convert() with "aaa" as a parameter, here is my output:
aaa
**676** *(value from cout)* = 26^(3-1)*1 **675** *(value of the variable)*
+26 = 26^(3-2)*1 700
+1 = 26^(3-3)*1 701
701
And here the code:
string alphabet="abcdefghijklmnopqrstuvwxyz";
unsigned long long Convert(string &str){
unsigned long long wvalue=0;
for(int i=0;i<str.size();++i){
size_t found=alphabet.find(str[i]);
if(found==string::npos)
cout<<"Please enter only lowercase letters of the english alphabet!"<<endl;
unsigned long long add=((found+1)*pow(26,(str.size()-(i+1))));
wvalue+=add;
if(i>0)cout<<"+";
cout<<"\t"<<((found+1)*pow(26,(str.size()-(i+1))))<<" = "<<"26^("<<str.size()<<"-"<<(i+1) <<")*"<<(found+1)<<"\t"<<wvalue<<endl;
}
return wvalue;
}
Chances are I'm missing something awfully obvious, but I cannot figure it out.
((found+1)*pow(26,(str.size()-(i+1))))
is doing the calculation, and it is doing as it is supposed to, the result within the cout-statment is correct. But the variable is substracted by 1 in the first two assignments.
pow is a floating-point function. It takes and returns floating point numbers. Assigning a floating-point number to an integer variable truncates it to an integer number, so it might have been 675.9999999 just before the assignment, which will turn into 675 when assigned to the integer variable add.
cout also rounds floating-point numbers, depending on the configuration for example to 6 significant digits. 676.0 is a better approximation than 675.999, so you see 676 in the output.
Since you don't want to calculate with real numbers but only with integral numbers, you better stay with integral functions. To take 26 to the power of n, better use multiplication n times. Since you already use a loop, and like to have the next power of 26 for every character, the best is to add a variable in which you keep the current power value, like this:
unsigned long long currentFactor = 1;
for (...) {
...
unsigned long long add = currentFactor * (found+1);
wvalue += add;
currentFactor *= 26;
}
Also note that you don't have to find the character in an alphabet string. You can also just use character arithmetic to do this:
int charNumber(char c) {
if (c >= 'a' && c <= 'z')
return c - 'a'; // calculate the position of c relative to 'a'
else
return -1; // error
}

Transform rational numbers to integers

How can I transform rational numbers like 1.24234 or 45.314 into integers like 124234 or 45314 also getting the number of decimal digits?
Convert to a string
Find the position of the decimal point.
Subtract that from the length of the above string, for the number of decimals.
Then take the point out of the string.
int i=0;
float a = 1.24234;
for(i; i<20; i++){
float b=pow(10,i);
if((a*b)%10==0)
break;
}
int c = pow(10,i-1);
int result = a*c;
I think this code will help you.
If your number is W.D (Whole.Decimal)
To get W just do (int)W.D.
To get D you can do W.D - (int) W.D
Now you have your whole number and your decimal point separated. To figure out your x10 multiplier on your W keep dividing D by 10 until you get a result that is less than 10.
Now: WxN+D
(where N is the number of times you divided by 10)
Note: I didn't write the code as an example, because I feel this may be a homework assignment. Also, if you are using very long (ie: precise floating points) this won't hold, and could likely overflow. Check your bounds before implementing something like this.

Using data type other than int as index value in C++ for loop

I am accepting an input from user as a float value.
This value can go up to "10 raised to power 18".
The next step involves finding all the divisors of this number. for which i am doing the following:
for(i=2; i<=n/2 ; i++)
{
if(n%i==0)
v.push_back(i);
}
Here, n is the number entered by the user.
Problem is that n is float and using it in if loop index causes it's value to be limited to '10 raised to the power 9'
Hence, is there any way to use data type other than int for using values of range '10 raised to power 18'?
You can use an unsigned long long which is 264 or roughly 1019
This assumes that your compiler supports 64-bit integers.
The question has been answered (use long long int), but wanted to point out that floats are called "floating point" for a reason. They incorporate an exponent, basically the position of the decimal point, which determines the precision of the mantissa. This conveniently allows you to both represent small numbers with high precision and large numbers with low precision, but not both at the same time.
For more details: http://en.wikipedia.org/wiki/IEEE_754-2008
Try this:
int main(void)
{
float i = 16777217.0f;
printf("i = %f\n", i);
i++;
printf("i+1 = %f\n", i);
}
w/ 32-bit floats this returns:
i = 16777216.000000
i+1 = 16777216.000000
So question of the day: what do you think will happen if you have a loop like this?
for(float f; f < 20000000; ++f)
{
// do stuff
}
Sure you can use other data types for loop , use any of the types mentioned here
I think a long double should be substantial.

C++ Radix sort algorithm

Trying to understand radix sort for my data structures class. My teacher showed us a sample of radix sort in C++. I don't understand what the for loop for the digits does, she said something about maximum digits. Also when I try this in VS it says log10 is an ambiguous call to an overloaded function.
void RadixSort(int A[], int size)
{
int d = 1;
for(int i = 0; i < size; ++i)
{
int digits_temp;
digits_temp=(int)log10(abs(A[i]!=0 ? abs(A[i]) : 1)) +1;
if(digits_temp > d)
d = digits_temp;
}
d += 1;
*rest of the implementation*
}
Can anyone explain what this for loop does and why i get that ambiguous call error? Thanks
That piece of code is just a search for the number of digits needed for the "longest" integer; that's probably needed to allocate some buffer later.
log10 gives you the power of ten that corresponds to its argument, which, rounded to the next integer (hence the +1 followed by the (int) cast, which results in truncation), gives you the number of digits required for the number.
The argument of log10 is a bit of a mess, since abs is called twice when just once would suffice. Still, the idea is to pass to log10 the absolute value of the number being examined if it's not zero, or 1 if it is zero - this because, if the argument were zero, the logarithm would diverge to minus infinity (which is not desirable in this case, I think that the conversion to int would lead to strange results).
The rest of the loop is just the search for the maximum: at each iteration it calculates the digits needed for the current int being examined, checks if it's bigger than the "current maximum" (d) and, if it is, it replaces the "current maximum".
The d+=1 may be for cautionary purposes (?) or for the null-terminator of the string being allocated, it depends on how d is used afterward.
As for the "ambiguous call" error: you get it because you are calling log10 with an int argument, which can be converted equally to float, double and long double (all types for which log10 is overloaded), so the overload to choose is not clear to the compiler. Just stick a (double) cast before the whole log10 argument.
By the way, that code could have been simplified/optimized by just looking for the maximum int (in absolute value) and then taking the base-10 logarithm to discover the number of digits needed.
Log base 10 + 1 gives you the total number of digits present in a number.
Essentially here, you are checking every element in the array A[] and if the element is == 0 you store 1 in the digits_temp variable.
You initialize d = 1 as a number should have atleast 1 digit, and if it has more than 1 you replace it with the number of digits calculated.
Hope that helps.
There are 3 types of definition for log10 function which are float,double,long double input.
log10( static_cast<double> (abs(A[i]!=0 ? abs(A[i]) : 1)) );
So you need to static cast it as double to avoid the error.
(int)log10(x)+1 gives the number of digit present in that number.
Rest is simple implementation of Radix Sort
You see the warning because log10 is defined for float, double and long double but not integer and it's being called with a integer. The compiler can convert the int into any of those types so the call is ambiguous.
The for loop is doing a linear search for the maximum of digits in any of the numbers in the array. It is unnecessarily complicated and slow because you can simply searched for the largest absolute value in A then taken the log10 of that.
void RadixSort(int A[], int size)
{
int max_abs = 1;
for(int i = 0; i < size; ++i)
{
if(abs(A[i] > max_abs)
max_abs = abs(A[i]);
}
int d += log10(float(max_abs));
/* rest of the implementation */
}
Rest of code is missing so cant exactly determined usage.
But basically Radix sort goes over all INTEGERS and sort them comparing Digit Digit starting from least significant upwards.
the first part of code only determines the max digit count+1 from integers in array, this could be used to normalize all numbers to same length for easy handling.
i.e (1,239,2134) to (0001,0239,2134)