I am working on this LeetCode problem to take an integer and reverse it, given that the reversed in is within the signed 32-bit range, in which case we should return 0.
and this code is doing just that, even with numbers like 1534236469/-1534236469. Except when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
I know this is not the cleanest code, but can you help me recognise what I'm missing?
#include<iostream>
#include<limits>
using namespace std;
class Solution {
public:
int reverse(int x) {
int a, r, y;
string num, fnum;
a = abs(x);
try{
while(a != 0){
r = a % 10;
a = a / 10;
num = to_string(r);
fnum = fnum + num;
y = stoi(fnum);
}
} catch(out_of_range& oor){
return 0;
}
if(x==0){
return 0;
} else if (x<0){
return -y;
} else {
return y;
}
}
};
int main(){
Solution mine;
cout << mine.reverse(-2147483648);
}
[...] when it comes to tricky numbers like -2147483648 where its not recognising it as out of range and instead returning 8 and not 0.
That number is "tricky" because it's equal to std::numeric_limits<int>::min() in your environment and given a two's complement representation of type int, it happens that std::abs(-2147483648) == -2147483648.
Next in your (contrived, I must say, there's no need to use a string here) code, the line num = to_string(r); would result in num = "-8", so that the loop would compose a string like "-8-4-6-3-8-4-7-4-1-2".
When applyed to strings like that, stoi doesn't throw an exception, it just stops parsing (you would have noticed it by passing and inspecting its other parameters).
If you want to check if the result is outside the range of an int, you could use locally a wider type (e.g. long long) and check the boundaries after the calculations or keep using int, but compare all the intermediate values with the limits before any calculation.
Related
I have been programming in C++ for a while now. I have seen previously that power function gives wrong answer for bigger powers due to precision issues but today while solving coding problems I saw that under the same type of parameters, pow() function gave different values when put inside a function vs when evaluated directly.
#include <iostream>
#include <math.h>
using namespace std;
long long n,d;
long long power(long long x)
{
return pow(100,x);
}
long long powersecond(long long x)
{
return pow(100,(int)x);
}
int main()
{
n = 68; d = 2;
cout << n*power(d) <<endl; // outputs 679932
cout << n*pow(100,d) <<endl; // outputs 680000
cout << n*powersecond(d) <<endl; // outputs 679932
cout << n*pow(100,(int)d) <<endl; // outputs 680000
return 0;
}
Notice that the answer doesn't change even after converting x to integer in powersecond() function.The answer is still 679932 even if d is int instead of long long int.
The compiler I used is gnu gcc compiler in VS Code.
The problem is that the output of pow is a floating point double. In your custom function you convert that output to long long, which will truncate if the value returned by pow is slightly low instead of slightly high. See Is floating point math broken?. When you call pow directly the value is kept as a double even after the multiplication, and output rounding gives you a more accurate result.
You expect the value returned by pow(100,2) to be 10000, but instead it might be 9999.99999999999 because of the way floating point works. When converted to integer, that becomes 9999; multiplied by 68, you have 679932.
On the other hand, 9999.99999999999 multiplied by 68 becomes 679999.999999999. That's close enough to 680000 that the output function << will round it for you. You can get a more exact figure if you apply output formatting.
Always write your own power function whenever needed. Change return type according to your requirement to avoid any kind of confusion.
long long int power(long long int a, long long int x) {
static long long int ans = 1;
if (x < 0)
return 1 / power(a, (-1 * x));
if (x == 1)
return a;
if (x == 0 or a == 1)
return 1;
if (x & 1)
ans = a * power((a * a), x / 2);
else
ans = power((a * a), x / 2);
return ans;
}
Here is recursive version .You can also write iterative version.
Went over this in class today:
const int tabsize = 100000;
int hash(string s) {
const int init = 21512712, mult = 96169, emergency = 876127;
int v = init;
for (int i=0; i<s.length(); i+=1)
v = v * mult + s[i];
if (v < 0) v = -v;
if (v < 0) v = emergency;
return v % tabsize;
}
Having some trouble figuring out what the last 2 if-statements are supposed to do.
Any ideas?
Thanks
The first if statement takes care of overflow behavior of signed integers. Thus if the integer gets too big that it wraps and becomes negative, this if statement ensures that only the positive integer is returned.
The second if statement is used to take care of the rare case of where v is 2147483648.
Note that positive signed 32 bit integers only go up to 231 - 1 or 2147483647 while the negative can go down to -231 or -2147483648.This number is negative and even negating it still gives a negative number. So that is what the emergency number is for
int main() {
int t = -2147483648;
std::cout << (-t) << std::endl;
}
They ensure the v is positive, because when you use the % operator on a negative number you can get a negative result which is not desirable for a hash value.
However, this does get into undefined behavior with the integer overflow so it might not work everywhere.
Here is the problem, Project Euler #45
And here's the code I wrote for it:
#include <iostream>
#include <math.h>
using namespace std;
bool ispent (long num){
long double x = (sqrt(24*num+1) + 1.0)/6.0;
if (floor(x)==x) return true;
else return false;
}
bool ishex (long num){
long double x = (sqrt(8*num+1) + 1.0)/4.0;
if (floor(x)==x) return true;
else return false;
}
int main(){
int i=286;
while(true){
long x = (i*(i+1))/2;
if((ispent(x)) && (ishex(x))){
cout << x;
break;
}
i++;
}
}
This gives the output 40755, whereas I require the next number. What could be the possible bug?
The issue is that using square roots to check if a number is pentagonal or hexagonal is imprecise, so the test will fail and you will overflow x.
To fix this, you can use a type with more precision, like replacing long with unsigned long, or even unsigned long long.
You are overflowing the 32-bit representation of x. If you know the next x is 1533776805, then an intermediate value of 2x is necessary, which at 3e9 overflows a signed integer. You can just fit this in an unsigned int, but I would use a 64-bit integer instead. #include <stdint.h>, and use int64_t for both i and x. But I agree with the other commenters, there's something suspicious about testing for exact double precision answers
I am doing a factorial program with strings because i need the factorial of Numbers greater than 250
I intent with:
string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;
}
}
But the problem is that atoi not works. How can i convert my string in a integer.
And The most important Do I want to know if the program of this way will work with the factorial of 400 for example?
Not sure why you are trying to use string. Probably to save some space by not using integer vector? This is my solution by using integer vector to store factorial and print.Works well with 400 or any large number for that matter!
//Factorial of a big number
#include<iostream>
#include<vector>
using namespace std;
int main(){
int num;
cout<<"Enter the number :";
cin>>num;
vector<int> res;
res.push_back(1);
int carry=0;
for(int i=2;i<=num;i++){
for(int j=0;j<res.size();j++){
int tmp=res[j]*i;
res[j]=(tmp+carry)%10 ;
carry=(tmp+carry)/10;
}
while(carry!=0){
res.push_back(carry%10);
carry=carry/10;
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
return 0;
}
Enter the number :400
Factorial of 400 :64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
There's a web site that will calculate factorials for you: http://www.nitrxgen.net/factorialcalc.php. It reports:
The resulting factorial of 250! is 493 digits long.
The result also contains 62 trailing zeroes (which constitutes to 12.58% of the whole number)
3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000
Many systems using C++ double only work up to 1E+308 or thereabouts; the value of 250! is too large to store in such numbers.
Consequently, you'll need to use some sort of multi-precision arithmetic library, either of your own devising using C++ string values, or using some other widely-used multi-precision library (GNU GMP for example).
The code below uses unsigned double long to calculate very large digits.
#include<iostream.h>
int main()
{
long k=1;
while(k!=0)
{
cout<<"\nLarge Factorial Calculator\n\n";
cout<<"Enter a number be calculated:";
cin>>k;
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
}
else
{
int numArr[10000];
int total,rem=0,count;
register int i;
//int i;
for(i=0;i<10000;i++)
numArr[i]=0;
numArr[10000]=1;
for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem;
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total;
}
i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is \n\n";
for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}
cout<<"\n\n";
}//while
return 0;
}
Output:
![Large Factorial Calculator
Enter a number be calculated:250
The factorial of 250 is
32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
You can make atoi compile by adding c_str(), but it will be a long way to go till getting factorial. Currently you have no b around. And if you had, you still multiply int by int. So even if you eventually convert that to string before return, your range is still limited. Until you start to actually do multiplication with ASCII or use a bignum library there's no point to have string around.
Your factorial depends on conversion to int, which will overflow pretty fast, so you want be able to compute large factorials that way. To properly implement computation on big numbers you need to implement logic as for computation on paper, rules that you were tought in primary school, but treat long long ints as "atoms", not individual digits. And don't do it on strings, it would be painfully slow and full of nasty conversions
If you are going to solve factorial for numbers larger than around 12, you need a different approach than using atoi, since that just gives you a 32-bit integer, and no matter what you do, you are not going to get more than 2 billion (give or take) out of that. Even if you double the size of the number, you'll only get to about 20 or 21.
It's not that hard (relatively speaking) to write a string multiplication routine that takes a small(ish) number and multiplies each digit and ripples the results through to the the number (start from the back of the number, and fill it up).
Here's my obfuscated code - it is intentionally written such that you can't just take it and hand in as school homework, but it appears to work (matches the number in Jonathan Leffler's answer), and works up to (at least) 20000! [subject to enough memory].
std::string operator*(const std::string &s, int x)
{
int l = (int)s.length();
std::string r;
r.resize(l);
std::fill(r.begin(), r.end(), '0');
int b = 0;
int e = ~b;
const int c = 10;
for(int i = l+e; i != e;)
{
int d = (s[i]-0x30) * x, p = i + b;
while (d && p > e)
{
int t = r[p] - 0x30 + (d % c);
r[p] = (t % c) + 0x30;
d = t / c + d / c;
p--;
}
while (d)
{
r = static_cast<char>((d % c) +0x30)+r;
d /= c;
b++;
}
i--;
}
return r;
}
In C++, the largest integer type is 'long long', and it hold 64 bits of memory, so obviously you can't store 250! in an integer type. It is a clever idea to use strings, but what you are basically doing with your code is (I have never used the atoi() function, so I don't know if it even works with strings larger than 1 character, but it doesn't matter):
covert the string to integer (a string that if this code worked well, in one moment contains the value of 249!)
multiply the value of the string
So, after you are done multiplying, you don't even convert the integer back to string. And even if you did that, at one moment when you convert the string back to an integer, your program will crash, because the integer won't be able to hold the value of the string.
My suggestion is, to use some class for big integers. Unfortunately, there isn't one available in C++, so you'll have to code it by yourself or find one on the internet. But, don't worry, even if you code it by yourself, if you think a little, you'll see it's not that hard. You can even use your idea with the strings, which, even tough is not the best approach, for this problem, will still yield the results in the desired time not using too much memory.
This is a typical high precision problem.
You can use an array of unsigned long long instead of string.
like this:
struct node
{
unsigned long long digit[100000];
}
It should be faster than string.
But You still can use string unless you are urgent.
It may take you a few days to calculate 10000!.
I like use string because it is easy to write.
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
const int MAXN = 90;
int n, m;
int a[MAXN];
string base[MAXN], f[MAXN][MAXN];
string sum, ans;
template <typename _T>
void Swap(_T &a, _T &b)
{
_T temp;
temp = a;
a = b;
b = temp;
}
string operator + (string s1, string s2)
{
string ret;
int digit, up = 0;
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) Swap(s1, s2), Swap(len1, len2);
while(len2 < len1) s2 = '0' + s2, len2++;
for (int i = len1 - 1; i >= 0; i--)
{
digit = s1[i] + s2[i] - '0' - '0' + up; up = 0;
if (digit >= 10) up = digit / 10, digit %= 10;
ret = char(digit + '0') + ret;
}
if (up) ret = char(up + '0') + ret;
return ret;
}
string operator * (string str, int p)
{
string ret = "0", f; int digit, mul;
int len = str.length();
for (int i = len - 1; i >= 0; i--)
{
f = "";
digit = str[i] - '0';
mul = p * digit;
while(mul)
{
digit = mul % 10 , mul /= 10;
f = char(digit + '0') + f;
}
for (int j = 1; j < len - i; j++) f = f + '0';
ret = ret + f;
}
return ret;
}
int main()
{
freopen("factorial.out", "w", stdout);
string ans = "1";
for (int i = 1; i <= 5000; i++)
{
ans = ans * i;
cout << i << "! = " << ans << endl;
}
return 0;
}
Actually, I know where the problem raised At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}
Expexted output for 14! = 87178291200
The logic should be:
unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}
However b may get overflowed. So you may use a bigger integral type.
Or you can use float type which is inaccurate but can hold much bigger numbers.
But it seems none of the built-in types are big enough.
im simple asking if this is ok. i was asked to do the following. Write a program that will continuously ask the user for positive integers (until the
user enters a negative integer at which the program will be terminated). Every
time the user inputs a positive integer the program will print out this integer in
reverse. Your program should have a function that accepts and integer and returns
an integer in reverse. To convert the integer to its reverse, your program will call
this function. at the end of each output i keep getting 0. please explain why. also if i use void main with the function i get garbage. please explain why. thanks in advance
this is my code....
#include<iostream>
#include<cstdlib>
using namespace std;
int reverseNum(int num){
for(int j=num; j>0; j--)
cout<<j<<" ";
cout<<endl;
return false;
}
int main(){
double enternum = 0;
do{
cout<<"Enter a positive number > 0, to begin countdown ";
cin >>enternum;
cout<<reverseNum(enternum);
cout<<endl;
}
while(enternum>0);
if(enternum<=0)
cout<<"Invalid entry, good bye.";
cout<<endl;
return 0;
}
because of this: return false; - I'll leave it to you to figure out the rest..
The function is supposed to reverse the integer and then return the result. For example, if the input is 123, then the function returns 321.
Your function outputs a count-down and returns 0 (=false).
To reverse a number, you can a) convert it to string, reverse the string, convert it back to integer; b) do it on integers directly with mathematical division / multiplication / addition / modulo operations.
In C++, you don't use void main().
A 0 because when you return false, the result of type bool is implicitly converted to an int and gets printed at the line cout<<reverseNum(enternum);
Also, In this line, double enternum = 0; you want an integer int.
From your text I thought the program was working as intended, but from reading the code I suppose it just counts down from the number. Was this what you wanted?
I'd have implemented it like this (and here the function returning an integer makes sense too):
int reverseNum(int num)
{
int reverse = 0;
[...] // Do the actual reversing
return reverse;
}
Your program should have a function that accepts and integer and returns an integer in reverse
your reverseNum function should return the reversed integer, not false. and it shouldn't print the number as well, it's the caller which supposed to print it.
if one does:
i = reverseNum(1234);
then i should contain 4321 as an integer (NOT string).
the reason you keep getting 0 is because false is equivalent to 0 as an integer.
You should read the C++ FAQ in its entirety. You should especially read this. You should also learn how to debug your code. If you stepped through your code in a debugger then all the answers that you have been given here will be obvious.
For good fun, I attempted a generic implementation that supports any integral or floating point type supported by your compiler.
Be warned, there are a number of issues:
reversing a floating point number is not well defined semantically (how to position the decimal separator? How do we handle exponential notation?)
floating point types are frequently inexact (at least common IEEE formats are) and hence scaling the input will introduce artificial fractional digits. I have not taken much effort to do proper rounding, so some numbers will reverse into strange things (e.g. 123.0 could reverse into 992.1 instead of 321.0 (untested for this input, try some yourself))
the implementation is laughably template-happy. Think of it as the instructional part of this playful answer.
Oh, uncomment the DEBUGTRACE definition to ... get debug tracing :)
See it live here [click]TM
#include <cmath>
#include <limits>
#include <iostream>
#define MAX_DECIMAL_FRACTION 5
#define DEBUGTRACE(x) // do { std::cerr << x; } while (false)
template <typename T, bool is_integer> struct reverse_impl;
template <typename T>
struct reverse_impl<T, true>
{
static T reverse(T input)
{
T output;
for (output = 0; input; input/=10)
output = (output * 10) + input % 10;
return output;
}
};
template <typename T>
struct reverse_impl<T, false>
{
static T reverse(T input)
{
if (std::abs(input) <= std::numeric_limits<T>::epsilon())
return T(0);
// scale input
int log10 = (int) (std::log(input)/std::log(T(10)));
input *= std::pow(10, MAX_DECIMAL_FRACTION);
input = std::floor(input);
input /= std::pow(10, log10+MAX_DECIMAL_FRACTION);
DEBUGTRACE("debug: scaled " << input << " digits: ");
int iteration = std::max(log10+MAX_DECIMAL_FRACTION, MAX_DECIMAL_FRACTION);
if (std::floor(input) < 1)
{
input *= 10;
iteration--;
}
T output;
for (output = T(0);
iteration-- && std::floor(input) >= 1;
input-=std::floor(input), input*=T(10))
{
output = (output / T(10)) + std::floor(input);
DEBUGTRACE(std::floor(input));
}
DEBUGTRACE(std::endl);
return output * std::pow(10, log10);
}
};
template <typename T>
T reverse(T input)
{
return reverse_impl<T, std::numeric_limits<T>::is_integer>::reverse(input);
}
int main()
{
std::cout << reverse(-123l) << std::endl;
std::cout << reverse(123ul) << std::endl;
std::cout << reverse(123456.0) << std::endl;
std::cout << reverse(0.027f) << std::endl;
return 0;
}
***//here is the simple solution to find reverse of a function***
#include<iostream.h>
#include<conio.h>
void main()
{
int n,a,c,d,b;
clrscr();
cout<<"enter five integers";
cin>>n;
a=n/10000;
n=n%10000;
b=n/1000;
n=n%1000;
c=n/100;
n=n%100;
d=n/10;
n=n%10;
cout<<"number in reverse order is"<<n<<d<<c<<b<<a;
getch();
}