Addition between `signed int` and `unsigned int` - c++

Here is an example from "C++ Primer" which indicates that signed int will be automatically converted to unsigned int when added with unsigned int. But the result I got seemed to be that unsigned int was casted to signed int instead. Could anyone tell me why?
Code:
#include <iostream>
using namespace std;
int main() {
int i = -1;
unsigned int u = 10;
cout << i + u << endl;
return 0;
}
Result:
9

That's a pretty uninteresting example. How can you tell if 9 is a signed or unsigned int (or long or short or ...)? It's in the range of all of these types.
Here's a better example:
int i = -12;
unsigned int u = 10;
cout << i + u << endl; // prints 4294967294
Or really:
static_assert(is_same<decltype(i+u), unsigned int>::value,
"wat");

Related

code to find the value of nCr shows the answer to some values as 0( Ex:30 15)

The following is the code:
#include
using namespace std;
int factorial(int num){
unsigned long long int fact=1;
for (int i = num; i >=1; i--)
{
fact=fact*i;
}
return fact;
}
int main()
{
unsigned long long int n,r,value;
cout<<"Enter a number whose nCr value is to be calculated (n and r respectively): ";
cin>>n>>r;
unsigned long long int a=factorial(n);
unsigned long long int b=factorial(r);
unsigned long long int c=factorial(n-r);
value=a/(b*c);
cout<<"The value of nCr is : "<<value;
return 0;
}
Why do I get the answer to some of the inputs like (30 15),(30 12), etc as 0.
30! is a very large 33-digit number, so that's overflowing the int variable your program is trying to store it in. If you print it out, you'll see the actual value that gets stored in a is smaller than the value of b*c in the denominator of the final computation, so value=a/(b*c); gets truncated to 0 by integer division.
Even if you return the result of factorial as an unsigned long long int the result of 30! will overflow, since it can only store 64 bits (and that's compiler dependent).
#include "stdafx.h"
#include <iostream>
unsigned long long int factorial(int num) {
unsigned long long int fact = 1;
for (int i = num; i >= 1; i--)
{
fact = fact * i;
}
return fact;
}
int main()
{
unsigned long long int n, r, value;
std::cout << "Enter a number whose nCr value is to be calculated (n and r respectively): ";
std::cin >> n >> r;
unsigned long long int a = factorial(n);
std::cout << "n! = " << a << std::endl;
unsigned long long int b = factorial(r);
std::cout << "r! = " << b << std::endl;
unsigned long long int c = factorial(n - r);
std::cout << "(n-r)! = " << c << std::endl;
std::cout << "r!(n-r)! = " << b*c << std::endl;
value = a / (b*c);
std::cout << "The value of nCr is : " << value << std::endl;
system("pause");
return 0;
}
Output:
Enter a number whose nCr value is to be calculated (n and r respectively): 30 12
n! = 9682165104862298112
r! = 479001600
(n-r)! = 6402373705728000
r!(n-r)! = 12940075575627743232
The value of nCr is : 0
Press any key to continue . . .
The main issue with your code is return type of factorial Method it should be same as the return type of "fact".
Second issue with code is that it cannot handle huge number above i.e, max value of unsigned long long int "18,446,744,073,709,551,615"(https://www.tutorialspoint.com/cplusplus/cpp_data_types.htm).
So just change the data types of variables fact,a,b,c and factorial method to "long double" which can accomodate 12 bytes of data.
Code below is just modified for tracing purpose... you can skip the line which you don't need. Be careful with data types. Code is modified as per your requirement for huge calculations.
Please reply if you have any confusion. And up-vote my answer if it looks right to you.
You can remove std:: from the code if not need by your compiler.
#include <iostream>
long double factorial(int num){
long double fact=1;
for (int i = num; i >=1; i--)
{
fact=fact*i;
}
return fact;
}
int main()
{
unsigned long long int n=0,r=0;
long double value=0;
std::cout<<"Enter a number whose nCr value is to be calculated (n and r respectively): ";
std::cin>>n>>r;
std::cout<<n;
std::cout<<r;
long double a=factorial(n);
long double b=factorial(r);
long double c=factorial(n-r);
std::cout<<"\na="<<a;
std::cout<<"\nb="<<b;
std::cout<<"\nc="<<c;
long double d = b*c;
std::cout<<"\nd="<<d;
value=(unsigned long long int)(a/d);
std::cout<<"\nThe value of nCr is : "<<value;
return 0;
`enter code here`}

Why is the size of the union greater than expected?

#include <iostream>
typedef union dbits {
double d;
struct {
unsigned int M1: 20;
unsigned int M2: 20;
unsigned int M3: 12;
unsigned int E: 11;
unsigned int s: 1;
};
};
int main(){
std::cout << "sizeof(dbits) = " << sizeof(dbits) << '\n';
}
output: sizeof(dbits) = 16, but if
typedef union dbits {
double d;
struct {
unsigned int M1: 12;
unsigned int M2: 20;
unsigned int M3: 20;
unsigned int E: 11;
unsigned int s: 1;
};
};
Output: sizeof(dbits) = 8
Why does the size of the union increase?
In the first and second union, the same number of bits in the bit fields in the structure, why the different size?
I would like to write like this:
typedef union dbits {
double d;
struct {
unsigned long long M: 52;
unsigned int E: 11;
unsigned int s: 1;
};
};
But, sizeof(dbits) = 16, but not 8, Why?
And how convenient it is to use bit fields in structures to parse bit in double?
members of a bit field will not cross boundaries of the specified storage type. So
unsigned int M1: 20;
unsigned int M2: 20;
will be 2 unsigned int using 20 out of 32 bit each.
In your second case 12 + 20 == 32 fits in a single unsigned int.
As for your last case members with different storage type can never share. So you get one unsigned long long and one unsigned int instead of a single unsigned long long as you desired.
You should use uint64_t so you get exact bit counts. unsigned int could e anything from 16 to 128 (or more) bit.
Note: bitfields are highly implementation defined, this is just the common way it usually works.

Unsigned long long Fibonacci numbers negative?

I've written a simple Fibonacci sequence generator that looks like:
#include <iostream>
void print(int c, int r) {
std::cout << c << "\t\t" << r << std::endl;
}
int main() {
unsigned long long int a = 0, b = 1, c = 1;
for (int r = 1; r <= 1e3; r += 1) {
print(c, r);
a = b;
b = c;
c = a + b;
}
}
However, as r gets around the value of 40, strange things begin to happen. c's value oscillate between negative and positive, despite the fact he's an unsigned integer, and of course the Fibonacci sequence can't be exactly that.
What's going on with unsigned long long integers?
Does c get too large even for a long long integer?
You have a narrowing conversion here print(c, r); where you defined print to take only int's and here you pass an unsigned long long. It is implementation defined.
Quoting the C++ Standard Draft:
4.4.7:3: If the destination type is signed, the value is
unchanged if it can be represented in the destination type; otherwise,
the value is implementation-defined.
But what typically happens is that: from the unsigned long long, only the bits that are just enough to fit into an int are copied to your function. The truncated int is stored in Twos complements, depending on the value of the Most Significant Bit. you get such alternation.
Change your function signature to capture unsigned long long
void print(unsigned long long c, int r) {
std::cout << c << "\t\t" << r << std::endl;
}
BTW, see Mohit Jain's comment to your question.

Why can't I use a long long int type ? c++

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.

The most efficient way to reverse a number

I am looking for an efficient algorithm to reverse a number, e.g.
Input: 3456789
Output: 9876543
In C++ there are plenty of options with shifting and bit masks but what would be the most efficient way ?
My platform: x86_64
Numbers range: XXX - XXXXXXXXXX (3 - 9 digits)
EDIT
Last digit of my input will never be a zero so there is no leading zeros problem.
Something like this will work:
#include <iostream>
int main()
{
long in = 3456789;
long out = 0;
while(in)
{
out *= 10;
out += in % 10;
in /= 10;
}
std::cout << out << std::endl;
return 0;
}
#include <stdio.h>
unsigned int reverse(unsigned int val)
{
unsigned int retval = 0;
while( val > 0)
{
retval = 10*retval + val%10;
val /= 10;
}
printf("returning - %d", retval);
return retval;
}
int main()
{
reverse(123);
}
You may convert the number to string and then reverse the string with STL algorithms. Code below should work:
long number = 123456789;
stringstream ss;
ss << number;
string numberToStr = ss.str();
std::reverse(numberToStr.begin(), numberToStr.end());
cout << atol(numberToStr.c_str());
You may need to include those relevant header files. I am not sure whether it is the most efficient way, but STL algorithms are generally very efficient.
static public int getReverseInt(int value) {
int resultNumber = 0;
for (int i = value; i != 0;) {
int d = i / 10;
resultNumber = (resultNumber - d) * 10 + i;
i = d;
}
return resultNumber;
}
I think this will be the fastest possible method without using asm. Note that d*10 + i is equivalent to i%10 but much faster since modulo is around 10 times slower than multiplication.
I tested it and it is about 25 % faster than other answers.
int ans=0;
int rev(int n)
{
ans=(ans+(n%10))*10; // using recursive function to reverse a number;
if(n>9)
rev(n/10);
}
int main()
{
int m=rev(456123); // m=32
return 0;
}
//Recursive method to find the reverse of a number
#include <bits/stdc++.h>
using namespace std;
int reversDigits(int num)
{
static int rev_num = 0;
static int base_pos = 1;
if(num > 0)
{
reversDigits(num/10);
rev_num += (num%10)*base_pos;
base_pos *= 10;
}
return rev_num;
}
int main()
{
int num = 4562;
cout << "Reverse " << reversDigits(num);
} ``
// recursive method to reverse number. lang = java
static void reverseNumber(int number){
// number == 0 is the base case
if(number !=0 ){
//recursive case
System.out.print(number %10);
reverseNumber(number /10);
}
}
This solution is not as efficient but it does solve the problem and can be useful.
It returns long long for any signed integer(int, long, long long, etc) and unsigned long long for any unsigned integer (unsigned int, unsigned long, unsigned long long, etc).
The char type depends of compiler implementation can be signed or unsigned.
#include <iostream>
#include <string>
#include <algorithm>
template <bool B>
struct SignedNumber
{
};
template <>
struct SignedNumber<true>
{
typedef long long type;
};
template <>
struct SignedNumber<false>
{
typedef unsigned long long type;
};
template <typename TNumber = int,
typename TResult = typename SignedNumber<std::is_signed<TNumber>::value>::type,
typename = typename std::void_t<std::enable_if_t<std::numeric_limits<TNumber>::is_integer>>>
TResult ReverseNumber(TNumber value)
{
bool isSigned = std::is_signed_v<TNumber>;
int sign = 1;
if (value < 0)
{
value *= -1;
sign = -1;
}
std::string str = std::to_string(value);
std::reverse(str.begin(), str.end());
return isSigned ? std::stoll(str) * sign : std::stoull(str) * sign;
}
int main()
{
std::cout << ReverseNumber(true) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber(false) << std::endl; //bool -> unsigned long long
std::cout << ReverseNumber('#') << std::endl; //char -> long long or unsigned long long
std::cout << ReverseNumber(46) << std::endl; //int -> long long
std::cout << ReverseNumber(-46) << std::endl; //int -> long long
std::cout << ReverseNumber(46U) << std::endl; //unsigned int -> unsigned long long
std::cout << ReverseNumber(46L) << std::endl; //long -> long long
std::cout << ReverseNumber(-46LL) << std::endl; //long long -> long long
std::cout << ReverseNumber(46UL) << std::endl; //unsigned long -> unsigned long long
std::cout << ReverseNumber(4600ULL) << std::endl; //unsigned long long -> unsigned long long
}
Output
1
0
64
64
-64
64
64
-64
64
64
Test this code
https://repl.it/#JomaCorpFX/IntegerToStr#main.cpp
If it is 32-bit unsigned integer (987,654,321 being max input) and if you have 4GB free memory(by efficiency, did you mean memory too?),
result=table[value]; // index 12345 has 54321, index 123 has 321
should be fast enough. Assuming memory is accessed at 100 ns time or 200 cycles and integer is 7 digits on average, other solutions have these:
7 multiplications,
7 adds,
7 modulo,
7 divisions,
7 loop iterations with 7 comparisons
if these make more than 100 nanoseconds / 200 cycles, then table would be faster. For example, 1 integer division can be as high as 40 cycles, so I guess this can be fast enough. If inputs are repeated, then data will coming from cache will have even less latency.
But if there are millions of reversing operations in parallel, then computing by CPU is absolutely the better choice (probably 30x-100x speedup using vectorized compute loop + multithreading) than accessing table. It has multiple pipelines per core and multiple cores. You can even choose CUDA/OpenCL with a GPU for extra throughput and this reversing solution from other answers look like perfectly embarrassingly parallelizable since 1 input computes independently of other inputs.
This is the easiest one:
#include<iostream>
using namespace std;
int main()
{
int number, reversed=0;
cout<<"Input a number to Reverse: ";
cin>>number;
while(number!=0)
{
reversed= reversed*10;
reversed=reversed+number%10;
number=number/10;
}
cout<<"Reversed number is: "<<reversed<<endl;
}