This question already has answers here:
How disastrous is integer overflow in C++?
(3 answers)
Closed 8 years ago.
when i try to add two long numbers it gives me minus result :
#include<iostream>
using namespace std;
int main ()
{
int a=1825228665;
int b=1452556585;
cout<<a+b;
return 0;
}
This gives me:
-1017182046
It's overflowing of the type. When you add two big number that the result can't be stored in chosen type it get overfloved. In most cases it will wraped the number, but it's not defined in the standard. So in some compilers the result is undefined.
For int and other numeric types when program can't store this big number in it we can see a overflow of it.
Lets say that int can store number from -10 to 10, when you do this:
int a = 10;
int b = a+1;
You will get -10 in b or some random value (it can be anything because the result is undefined)
That's because the results overflows. Since the first bit in numeric signed data types is used for the sign representation. The specific representation is called Two's complement (Wikipedia article here). Practically a 1 in this bit maps to a - while a 0 to +. The solution to this problem is using a larger data type like long. Larger it means that the memory used to store it is bigger so the range of values increases.
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
Below is the program I've written to find the exponent of 6, but I this its giving wrong output or I may be wrong somewhere, I'm unable to figure out here.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll t;
cin>>t;
cout<<log(t)/log(6)<<"\n";
cout<<floor(log(t)/log(6))<<"\n";
cout<<ceil(log(t)/log(6));
return 0;
}
Input:-
216
Output:-
3
3
4
Since 216 can be written as 6*6*6, so whether there is ceil or floor the output should be 3 in all three cases.
Answering to my own question, this problem can be solved by setting small precision(here up to 2 decimal digits), below is the program for the same.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
cout<<log(t)/log(6)<<"\n";
cout<<floor((floor(log(t)/log(6)*100.0)/100.0))<<"\n";
cout<<ceil((floor(log(t)/log(6)*100.0)/100.0));
return 0;
}
The log function - like most floating point calculations - is imprecise. There is often tiny amount of error in the result. In your case, you did not get the exact 3, but some value slightly greater than 3. When you apply ceil or floor to such imprecise result, you may increase or reduce the amount of the error up to a whole number. In this case you increased the error by ceiling the result from nearly correct integer to exactly following integer).
If you want to find the exponent of an integer with respect to a given radix, then repeated division and checking the remainder is a good starting point. There are faster ways (related to exponentation by squaring) which you could investigate if you want to squeeze out more performance.
The problem is that using the ratio of two log calls and truncating that to an int is bound to give you an inexact answer since the result of a log most likely cannot be represented exactly as a floating point value, and the log function itself may not recover the best floating point value possible (neither the C++ standard nor IEEE754 insist on that).
Finally, on #define ll long long, don't do that. It only serves to obfuscate. And #include<bits/stdc++.h> is not portable C++.
This question already has answers here:
Multiplication of two integers in C++
(3 answers)
Closed 2 years ago.
I am trying to execute a simple long multiplication but it is not showing the correct the output.
here is the sample code
'''
#include<iostream>
using namespace std;
int main ()
{
long long int c=100000*90000;
cout<<c;
return 0;
}
'''
cout of variable c is: 410065408
I dont know why it is displaying the garbage value instead of 9000000000.
On a platform with a 32 bit int, 100000 and 90000 are int types (Note that on platforms with a 16 bit int they would be long types and a similar analysis to what I present here would apply to a 32 bit long.)
Hence you are multiplying two int types. You are overflowing the int, with undefined results, although it's no coincidence that 9000000000 - 410065408 is a multiple of 232 (but don't rely on that since it's little more than a manifestation of undefined behaviour).
100000LL * 90000
is a fix.
The type of 100000 is (probably 1) int (on your system). The type of 90000 (probably) is int (on your system). You are multiplying two int objects. int is guaranteed to represent numbers up to 32'767. On modern x86 systems it can represent up to 2'147'483'647. Those maximums are less than 9'000'000'000. As such, the behaviour of the program is undefined.
The fact that you initialise a long long using this overflowed int is irrelevant to the result. You must perform the multiplication on long long objects to get a 64 bit (at least) multiplication.
1 Assuming those numbers are representable as int on your system, which it is on modern x86 systems. It could be long on some systems.
This question already has answers here:
Representing integers in doubles
(4 answers)
Closed 5 years ago.
My question is whether all integer values are guaranteed to have a perfect double representation.
Consider the following code sample that prints "Same":
// Example program
#include <iostream>
#include <string>
int main()
{
int a = 3;
int b = 4;
double d_a(a);
double d_b(b);
double int_sum = a + b;
double d_sum = d_a + d_b;
if (double(int_sum) == d_sum)
{
std::cout << "Same" << std::endl;
}
}
Is this guaranteed to be true for any architecture, any compiler, any values of a and b? Will any integer i converted to double, always be represented as i.0000000000000 and not, for example, as i.000000000001?
I tried it for some other numbers and it always was true, but was unable to find anything about whether this is coincidence or by design.
Note: This is different from this question (aside from the language) since I am adding the two integers.
Disclaimer (as suggested by Toby Speight): Although IEEE 754 representations are quite common, an implementation is permitted to use any other representation that satisfies the requirements of the language.
The doubles are represented in the form mantissa * 2^exponent, i.e. some of the bits are used for the non-integer part of the double number.
bits range precision
float 32 1.5E-45 .. 3.4E38 7- 8 digits
double 64 5.0E-324 .. 1.7E308 15-16 digits
long double 80 1.9E-4951 .. 1.1E4932 19-20 digits
The part in the fraction can also used to represent an integer by using an exponent which removes all the digits after the dot.
E.g. 2,9979 ยท 10^4 = 29979.
Since a common int is usually 32 bit you can represent all ints as double, but for 64 bit integers of course this is no longer true. To be more precise (as LThode noted in a comment): IEEE 754 double-precision can guarantee this for up to 53 bits (52 bits of significand + the implicit leading 1 bit).
Answer: yes for 32 bit ints, no for 64 bit ints.
(This is correct for server/desktop general-purpose CPU environments, but other architectures may behave differently.)
Practical Answer as Malcom McLean puts it: 64 bit doubles are an adequate integer type for almost all integers that are likely to count things in real life.
For the empirically inclined, try this:
#include <iostream>
#include <limits>
using namespace std;
int main() {
double test;
volatile int test_int;
for(int i=0; i< std::numeric_limits<int>::max(); i++) {
test = i;
test_int = test;
// compare int with int:
if (test_int != i)
std::cout<<"found integer i="<<i<<", test="<<test<<std::endl;
}
return 0;
}
Success time: 0.85 memory: 15240 signal:0
Subquestion:
Regarding the question for fractional differences. Is it possible to have a integer which converts to a double which is just off the correct value by a fraction, but which converts back to the same integer due to rounding?
The answer is no, because any integer which converts back and forth to the same value, actually represents the same integer value in double. For me the simplemost explanation (suggested by ilkkachu) for this is that using the exponent 2^exponent the step width must always be a power of two. Therefore, beyond the largest 52(+1 sign) bit integer, there are never two double values with a distance smaller than 2, which solves the rounding issue.
No. Suppose you have a 64-bit integer type and a 64-bit floating-point type (which is typical for a double). There are 2^64 possible values for that integer type and there are 2^64 possible values for that floating-point type. But some of those floating-point values (in fact, most of them) do not represent integer values, so the floating-point type can represent fewer integer values than the integer type can.
The answer is no. This only works if ints are 32 bit, which, while true on most platforms, isn't guaranteed by the standard.
The two integers can share the same double representation.
For example, this
#include <iostream>
int main() {
int64_t n = 2397083434877565865;
if (static_cast<double>(n) == static_cast<double>(n - 1)) {
std::cout << "n and (n-1) share the same double representation\n";
}
}
will print
n and (n-1) share the same double representation
I.e. both 2397083434877565865 and 2397083434877565864 will convert to the same double.
Note that I used int64_t here to guarantee 64-bit integers, which - depending on your platform - might also be what int is.
You have 2 different questions:
Are all integer values perfectly represented as doubles?
That was already answered by other people (TL;DR: it depends on the precision of int and double).
Consider the following code sample that prints "Same": [...] Is this guaranteed to be true for any architecture, any compiler, any values of a and b?
Your code adds two ints and then converts the result to double. The sum of ints will overflow for certain values, but the sum of the two separately-converted doubles will not (typically). For those values the results will differ.
The short answer is "possibly". The portable answer is "not everywhere".
It really depends on your platform, and in particular, on
the size and representation of double
the range of int
For platforms using IEEE-754 doubles, it may be true if int is 53-bit or smaller. For platforms where int is larger than double, it's obviously false.
You may want be able to investigate the properties on your runtime host, using std::numeric_limits and std::nextafter.
This question already has an answer here:
Integer division always zero [duplicate]
(1 answer)
Closed 3 years ago.
As the title says, this code is meant to calculate the probability of 2 people having the same birthday in a group of 5 but it just outputs 1, I'm fairly new to C++ so any help would be appreciated.
#include <iostream>
using namespace std;
int main(){
float p;
p=1-(364/365)*(363/365)*(362/365)*(361/365);
cout<<p;
}
Put a .0 on each number, that way is treated as a double instead of an integer. Integer division (364/365) equals 0
p=1.0-(364.0/365.0)*(363.0/365.0)*(362.0/365.0)*(361.0/365.0);
This is because after calculation 364/365 the calculates answer is an integer which is 0.
To make it work change it like this.
p=1-(364/365.0)*(363/365.0)*(362/365.0)*(361/365.0);
You need to cast the integers to floats as / rounds to the largest integer below the result when both types are int:
p=1-(float(364)/float(365))*(float(363)/float(365))*(float(362)/float(365))*(float(361)/float(365));
This question already has answers here:
Understanding the bitwise AND Operator
(4 answers)
Closed 8 years ago.
Does the statement return a single bit or concatenation of bits.
if(mask[i] & groupbit) {
//...
}
with:
i = an integer
mask[i] = an element of integer pointer
groupbit = An integer
It will result in an entire integer. When you use the bitwise and, each bit of the two values are and'ed together, and each bit in the result is set accordingly. The result will be the same number of bits as the values being and'ed together.
This is assuming you're using two integer variables.
Assuming mask is a pointer to an integer type the compiler will do the following:
Access the i-th element of the mask "array" as an integer
make sure both operands are of the same size (this may involve bit-expansion or truncation)
do a bit-wise AND
if there was a single bit set in the result from the previous AND operation the value will be treated as true, otherwise as false(if every single bit of the result is 0)