Big inputs(64 bits) giving unexpected results while Counting number of bits in a 64-bit integer in c++ [duplicate] - c++

This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 7 years ago.
i am trying to count number of bits in 64 bit integer but it shows some unexpected.here is the code.
counting bits is was not the major part but some unexpected output is....plz have a look on input and output!!!!
#include<iostream>
#include<math.h>
#include<stdint.h>
#include<cstdio>
using namespace std;
int64_t t,n,ans;
int main(){
cin>>t;
while(t--){
int64_t ans=0;
cin>>n;
/*
while(n>0LL){
n>>=1LL;
ans++;
}//*/
ans=floor(log2(n));
//ans=floor(log2l(n));
cout<<ans<<"\n";
}
return 0;
}
the input and output is this
10
18446744073709551615
63 (number of bits in 18446744073709551615) should be printed only once and console should be waiting till i input another number and the count the number of bits in other number.but it is not happening.The output comes is like this....
63
63
63
63
63
63
63
63
63
63
plz help me ragarding the same.

In addition to the above explanations how to properly count bits this is why it goes on until t exhausted without asking for more input:
Problem is in the size of your value: 18446744073709551615
It is bigger than signed long long. So, once you enter it into cin the stream becomes not good(): failbit is set:
failbit - Logical error on i/o operation
From here http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ :
Extracts and parses characters ... interpret them as ... the proper type...
...Then (if good), ...adjusting the stream's internal state flags accordingly.
So, in your case
you read first value 18446744073709551615, failbit is set.
you process whatever is in the n (should be numeric_limits<long long>::max()), ignoring any input errors
you try reading next value
since failbit is set cin>>n does nothing leaving old n as is
this repeats until t exhausted

On x86-64 there's the POPCNT instruction. https://en.wikipedia.org/wiki/SSE4#POPCNT_and_LZCNT
https://msdn.microsoft.com/en-us/library/bb385231.aspx
unsigned __int64 __popcnt64(
unsigned __int64 value
);
GCC
__builtin_popcountll ((long long) x);

Related

Bitwise complement operator (~) not working at a point in C

This code takes 2 byte int and exchanges the bytes.
Why the line in this code i commented seems to be not working?
INPUT/OUTPUT
*When i input 4 expected output is 1024 instead the 9th to 16th bits were all set to "1" after passing that line.
*Then i tried input 65280, whose expected output is 255 instead it outputs 65535 (sets all 16 bits to "1"
#include<stdio.h>
int main(void)
{
short unsigned int num;
printf("Enter the number: ");
fscanf(stdin,"%hu",&num);
printf("\nNumber with no swap between bytes---> %hu\n",num);
unsigned char swapa,swapb;
swapa=~num;
num>>=8;
swapb=~num;
num=~swapa;
num<<=8;
num=~swapb; //this line is not working why
printf("Swaped bytes value----> %hu\n",num);
}
Integral promotions also the current value of num is getting clobbering by the commented line, probably want a |=, +=, or ^=.

Why is int i = 1<<31 == -2147483648 instead of 2147483648? [duplicate]

This question already has answers here:
Why is the maximum value of an unsigned n-bit integer 2ⁿ-1 and not 2ⁿ?
(12 answers)
Closed 5 years ago.
I was trying to understand the bitwise operation and according to me integer contains 32 bit and from LSB 0th position to MSB 31st position so if I set left shift 1 to 31 place I think I should get 2^31 and the binary representation of it would be 10000000 00000000 00000000 00000000 so why in am getting the result as negative ? and please correct me if I am wrong.
#include<bits/stdc++.h>
using namespace std;
int main(){
int i=1<<31;
cout<<i;
return 0;
}
Integer is a 32bit data type and its most significant bit stands for the sign. (That is the 32nd bit)
Therefore you're getting a negative value
C++ does not specify the behaviour of programs that include 1<<31.
On a different platform you may get a different answer, or a compilation error, or a program that formats your drive, or any other behaviour.

C++ : storing a 13 digit number always fails

I'm programming in C++ and I have to store big numbers in one of my exercices.
The biggest number i have to store is : 9 780 321 563 842.
Each time i try to print the number (contained in a variable) it gives me a wrong result (not that number).
A 32bit type isn't enough since 2^32 is a 10 digit number and I have to store a 13 digit number. But with 64 bits you can respresent a number that has 20digits. So I tried using the type "uint64_t" but that didn't work for me and I really don't understand why.
So I searched on the internet to find which type would be sufficient for my variable to fit in. I saw on this forum persons with the same problem but they solved it using long long int or long double as type. But none worked for me (neither did long float).
I really don't know which other type could store that number, as I tried a lot but nothing worked for me.
Thanks for your help! :)
--
EDIT : The code is a bit long and complex and would not matter for the question, so this is actually what I do with the variable containing that number :
string barcode_s = "9780321563842";
uint64_t barcode = atoi(barcode_s.c_str());
cout << "Barcode is : " << barcode << endl;
Off course I don't put that number in a variable (of type string) "barcode_s" to convert it directly to a number, but that's what happen in my program. I read text from an input file and put it in "barcode_s" (the text I read and put in that variable is always a number) and then I convert that string to a number (using atoi).
So i presume the problem comes from the "atoi" function?
Thanks for your help!
The problem is indeed atoi: it returns an int, which is on most platforms a 32-bits integer. Converting to uint64_t from int will not magically restore the information that has been lost.
There are several solutions, though. In C++03, you could use stringstream to handle the conversion:
std::istringstream stream(barcode_s);
unsigned long barcode = 0;
if (not (stream >> barcode)) { std::abort(); }
In C++11, you can simply use stoul or stoull:
unsigned long long const barcode = std::stoull(barcode_s);
Your number 9 780 321 563 842 is hex 8E52897B4C2, which fits into 44 bits (4 bits per hex digit), so any 64 bit integer, no matter if signed or unsigned, will have space to spare. 'uint64_t' will work, and it will even fit into a 'double' with no loss of precision.
It follows that the remaining issue is a mistake in your code, usually that is either an accidental conversion of the 64 bit number to another type somewhere, or you are calling the wrong fouction to print a 64 bit integer.
Edit: just saw your code. 'atoi' returns int. As in 'int32_t'. Converting that to 'unit64_t' will not reconstruct the 64 bit number. Have a look at this: http://msdn.microsoft.com/en-us/library/czcad93k.aspx
The atoll () function converts char* to a long long.
If you don't have the longer function available, write your own in the mean time.
uint64_t result = 0 ;
for (unsigned int ii = 0 ; str.c_str()[ii] != 0 ; ++ ii)
{
result *= 10 ;
result += str.c_str () [ii] - '0' ;
}

how to store larger binary numbers in bitset (C++)

i m trying to make a program to convert a number into it's binary.
Code:
#include<iostream>
#include<algorithm>
#include<bitset>
using namespace std;
int main()
{
int a;
string k;
bitset<CHAR_BIT> n;
cin>>a;
n=bitset<CHAR_BIT>(a);
cout<<n<<" ";
return 0;
}
The program gives wrong answer for 585 as it contains more than 6 binary digits. How can i such greater numbers?
585 mod 256 = 73 (assuming CHAR_BIT is 8)
73 in base 2 = 0b01001001
The program does print 01001001.
I don't see there's anything wrong.
If you want to store the whole range of a, the bitset should be declared as
bitset<CHAR_BIT * sizeof(a)> n (a);
A bitset has a fixed number of bits. You specify bitset<CHAR_BIT> -- on most systems, CHAR_BIT is 8 so you will have an 8-bit bitset. When you try to stuff a bigger number into the bitset, the most significant bits are discarded.
If you know in advance the largest numbers you will have to deal with, you can specify eg bitset<16> or bitset<32>. If you don't, you may have to use some other datatype.

Unsigned long with negative value

Please see the simple code below:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(void)
{
unsigned long currentTrafficTypeValueDec;
long input;
input=63;
currentTrafficTypeValueDec = (unsigned long) 1LL << input;
cout << currentTrafficTypeValueDec << endl;
printf("%u \n", currentTrafficTypeValueDec);
printf("%ld \n", currentTrafficTypeValueDec);
return 0;
}
Why printf() displays the currentTrafficTypeValueDec (unsigned long) with negative value?
The output is:
9223372036854775808
0
-9223372036854775808
%d is a signed formatter. Reinterpreting the bits of currentTrafficTypeValueDec (2 to the 63rd power) as a signed long gives a negative value. So printf() prints a negative number.
Maybe you want to use %lu?
You lied to printf by passing it an unsigned value while the format spec said it would be a signed one.
Fun with bits...
cout is printing the number as an Unsigned Long, all 64 bits are significant and print as unsigned binary integer (I think the format here would be %lu).
printf(%u ... treats the input as an normal unsigned integer (32 bits?). This causes bits 33 through 64 to drop off - leaving zero.
printf(%ld ... treats the input as a 64 bit signed number and just prints it out as such.
The thing you might find confusing about the last printf is that it gives the same absolute value as cout, but with a minus sign. When viewing as an unsigned integer all 64 bits are significant in producing the integer value. However for signed numbers, bit 64 is the sign bit. When the sign bit is set (as it is in your example) it indicates the remaining 63 bits are to be treated as a negative number represented in 2's compliment. Positive numbers are printed simply by converting their binary value to decimal. However for a negative number the following happens: Print a negative sign, XOR bits 1 through 63 with binary '1' bits, add 1 to the result and print the unsigned value. By dropping the sign bit (bit 64) you end up with 63 '0' bits, XORing with '1' bits gives you 63 '1' bits, add +1 and the whole thing rolls over to give you an unsigned integer having bit 64 set to '1' and the rest set to '0' - which is the same thing you got with cout BUT, as a negative number.
Once you have worked out why the above explanation is correct you should also be able to make sense out of this
Because you're shifting the 1 into the sign bit of the variable. When you print it as a signed value, it's negative.
the variable doesn't carry its type in itself. You specify to printf its type. Try:
printf("%lu \n", currentTrafficTypeValueDec);
because ld meand long signed that is not true.
You're printing %ld, or a long signed decimal. That's why it's returning a negative value.