I am doing some mathematical calculations (trying to convert Matlab code into C++, using VS2010) and I need to be able to tell if at some point I get a negative 0.
According to the IEEE standard -0/+0 differ only in the sign bit (the rest are 0).
I have used the following piece of code (post) to interpret my double as a unsigned char
double f = -5;
unsigned char *c = reinterpret_cast<unsigned char *>(&f);
for(int i=(sizeof(double)-1); i>=0; i--){
printf("%02X", c[i]);
}
Trying it with 5/-5 I get the expected result:
C014000000000000 (-5)
4014000000000000 (5)
But when I try it with 0/-0 I get only zeros in both case. VS2010 states that they are IEEE compliant (msdn) so I'm not sure which part of it I'm not getting.
If 0/-0 are indeed stored in the memory in the exact same way, there is no way I can tell them apart if I need to so I should stop wasting my time :) Right?
If you write
double d = -0;
the following will happen:
First, -0 will be evaluated, which is of type int, because 0 is of type int. The result will be 0. Then 0 will be converted to double and assigned thus being +0.0, and not -0.0
double d = -0.0; // is your solution.
In addition to Armen's good answer, you should use signbit to detect this. Doing so will protect you from endian issues:
#include <iostream>
#include <cmath>
int main()
{
std::cout << std::signbit(0.0) << '\n';
std::cout << std::signbit(-0.0) << '\n';
}
0
1
Same kind of function rewritten into shorter form:
static inline unsigned bool signbit(double& d)
{
return ( ((unsigned char*)&d)[sizeof(double)-1] & 0x80) != 0;
}
int EstimateDoubleBufferSize( double& d )
{
int len = 0;
if( signbit(d) ) //if ( d < 0 )
{
d = -d;
len++;
}
d += 0.0000005;
int m = (int) log10(d);
if( m < 0 )
m = 1; // 0.xxxx - include 0
else
m++; // Include first character
len += m + 1 /*dot*/ + 6 /* precision after . */;
return len;
}
Also I needed to figure out microsoft c++ compiler sprintf size - included function for that as well.
Related
I've written a program, which shows binary representation of a particular integer value, using bitwise operators in C++. For even numbers it works as I expect, but for odd it adds 1 to the left of the binary representation.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{
unsigned int a = 128;
for (int i = sizeof(a) * 8; i >= 0; --i) {
if (a & (1UL << i)) { // if i-th digit is 1
cout << 1; // Output 1
}
else {
cout << 0; // Otherwise output 0
}
}
cout << endl;
system("pause");
return 0;
}
Results:
For a = 128: 000000000000000000000000010000000,
For a = 127: 100000000000000000000000001111111
You might prefer CHAR_BIT macro instead of raw 8 (#include <climits>).
Consider your start value! Assuming unsigned int having 32 bit, your start value is int i = 4*8, so 1U << i shifts the value out of range. This is undefined behaviour and could result in anything, obviously, your specific compiler or hardware shifts %32, thus you get an initial value & 1, resulting in the unexpected leading 1... Did you notice that you actually printed out 33 digits instead of only 32?
The problem is here:
for (int i = sizeof(a) * 8; i >= 0; --i) {
it should be:
for (int i = sizeof(a) * 8; i-- ; ) {
http://coliru.stacked-crooked.com/a/8cb2b745063883fa
My objective is to write an algorithm that would be able to convert a long number into a binary number stored in a string.
Here is my current block of code:
#include <iostream>
#define LONG_SIZE 64; // size of a long type is 64 bits
using namespace std;
string b10_to_b2(long x)
{
string binNum;
if(x < 0) // determine if the number is negative, a number in two's complement will be neg if its' first bit is zero.
{
binNum = "1";
}
else
{
binNum = "0";
}
int i = LONG_SIZE - 1;
while(i > 0)
{
i --;
if( (x & ( 1 << i) ) == ( 1 << i) )
{
binNum = binNum + "1";
}
else
{
binNum = binNum + "0";
}
}
return binNum;
}
int main()
{
cout << b10_to_b2(10) << endl;
}
The output of this program is:
00000000000000000000000000000101000000000000000000000000000001010
I want the output to be:
00000000000000000000000000000000000000000000000000000000000001010
Can anyone identify the problem? For whatever reason the function outputs 10 represented by 32 bits concatenated with another 10 represented by 32 bits.
why would you assume long is 64 bit?
try const size_t LONG_SIZE=sizeof(long)*8;
check this, the program works correctly with my changes
http://ideone.com/y3OeB3
Edit: and ad #Mats Petersson pointed out you can make it more robust by changing this line
if( (x & ( 1 << i) ) == ( 1 << i) )
to something like
if( (x & ( 1UL << i) ) ) where that UL is important, you can see his explanation the the comments
Several suggestions:
Make sure you use a type that is guaranteed to be 64-bit, such as uint64_t, int64_t or long long.
Use above mentioned 64-bit type for your variable i to guarantee that the 1 << i calculates correctly. This is caused by the fact that shift is only guaranteed by the standard when the number of bits shifted are less or equal to the number of bits in the type being shifted - and 1 is the type int, which for most modern platforms (evidently including yours) is 32 bits.
Don't put semicolon on the end of your #define LONG_SIZE - or better yet, use const int long_size = 64; as this allows all manner of better behaviour, for example that you in the debugger can print long_size and get 64, where print LONG_SIZE where LONG_SIZE is a macro will yield an error in the debugger.
How do I detect the length of an integer? In case I had le: int test(234567545);
How do I know how long the int is? Like telling me there is 9 numbers inside it???
*I have tried:**
char buffer_length[100];
// assign directly to a string.
sprintf(buffer_length, "%d\n", 234567545);
string sf = buffer_length;
cout <<sf.length()-1 << endl;
But there must be a simpler way of doing it or more clean...
How about division:
int length = 1;
int x = 234567545;
while ( x /= 10 )
length++;
or use the log10 method from <math.h>.
Note that log10 returns a double, so you'll have to adjust the result.
Make a function :
int count_numbers ( int num) {
int count =0;
while (num !=0) {
count++;
num/=10;
}
return count;
}
Nobody seems to have mentioned converting it to a string, and then getting the length. Not the most performant, but it definitely does it in one line of code :)
int num = -123456;
int len = to_string(abs(num)).length();
cout << "LENGTH of " << num << " is " << len << endl;
// prints "LENGTH of 123456 is 6"
You can use stringstream for this as shown below
stringstream ss;
int i = 234567545;
ss << i;
cout << ss.str().size() << endl;
if "i" is the integer, then
int len ;
char buf[33] ;
itoa (i, buf, 10) ; // or maybe 16 if you want base-16 ?
len = strlen(buf) ;
if(i < 0)
len-- ; // maybe if you don't want to include "-" in length ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int i=2384995;
char buf[100];
itoa(i, buf, 10); // 10 is the base decimal
printf("Lenght: %d\n", strlen(buf));
return 0;
}
Beware that itoa is not a standard function, even if it is supported by many compilers.
len=1+floor(log10(n));//c++ code lib (cmath)
looking across the internet it's common to make the mistake of initializing the counter variable to 0 and then entering a pre-condition loop testing for as long as the count does not equal 0. a do-while loop is perfect to avoid this.
unsigned udc(unsigned u) //unsigned digit count
{
unsigned c = 0;
do
++c;
while ((u /= 10) != 0);
return c;
}
it's probably cheaper to test whether u is less than 10 to avoid the uneccessary division, increment, and cmp instructions for cases where u < 10.
but while on that subject, optimization, you could simply test u against constant powers of ten.
unsigned udc(unsigned u) //unsigned digit count
{
if (u < 10) return 1;
if (u < 100) return 2;
if (u < 1000) return 3;
//...
return 0; //number was not supported
}
which saves you 3 instructions per digit, but is less adaptable for different radixes inaddition to being not as attractive, and tedious to write by hand, in which case you'd rather write a routine to write the routine before inserting it into your program. because C only supports very finite numbers, 64bit,32bit,16bit,8bit, you could simply limit yourself to the maximum when generating the routine to benefit all sizes.
to account for negative numbers, you'd simply negate u if u < 0 before counting the number of digits. of course first making the routine support signed numbers.
if you know that u < 1000,
it's probably easier to just write, instead of writing the routine.
if (u > 99) len = 3;
else
if (u > 9) len = 2;
else len = 1;
Here are a few different C++ implementations* of a function named digits() which takes a size_t as argument and returns its number of digits. If your number is negative, you are going to have to pass its absolute value to the function in order for it to work properly:
The While Loop
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
The Exhaustive Optimization Technique
int digits(size_t i) {
if (i > 9999999999999999999ull) return 20;
if (i > 999999999999999999ull) return 19;
if (i > 99999999999999999ull) return 18;
if (i > 9999999999999999ull) return 17;
if (i > 999999999999999ull) return 16;
if (i > 99999999999999ull) return 15;
if (i > 9999999999999ull) return 14;
if (i > 999999999999ull) return 13;
if (i > 99999999999ull) return 12;
if (i > 9999999999ull) return 11;
if (i > 999999999ull) return 10;
if (i > 99999999ull) return 9;
if (i > 9999999ull) return 8;
if (i > 999999ull) return 7;
if (i > 99999ull) return 6;
if (i > 9999ull) return 5;
if (i > 999ull) return 4;
if (i > 99ull) return 3;
if (i > 9ull) return 2;
return 1;
}
The Recursive Way
int digits(size_t i) { return i < 10 ? 1 : 1 + digits(i / 10); }
Using snprintf() as a Character Counter
⚠ Requires #include <stdio.h> and may incur a significant performance penalty compared to other solutions. This method capitalizes on the fact that snprintf() counts the characters it discards when the buffer is full. Therefore, with the right arguments and format specifiers, we can force snprintf() to give us the number of digits of any size_t.
int digits(size_t i) { return snprintf (NULL, 0, "%llu", i); }
The Logarithmic Way
⚠ Requires #include <cmath> and is unreliable for unsigned integers with more than 14 digits.
// WARNING! There is a silent implicit conversion precision loss that happens
// when we pass a large int to log10() which expects a double as argument.
int digits(size_t i) { return !i? 1 : 1 + log10(i); }
Driver Program
You can use this program to test any function that takes a size_t as argument and returns its number of digits. Just replace the definition of the function digits() in the following code:
#include <iostream>
#include <stdio.h>
#include <cmath>
using std::cout;
// REPLACE this function definition with the one you want to test.
int digits(size_t i)
{
int count = 1;
while (i /= 10) {
count++;
}
return count;
}
// driver code
int main ()
{
const int max = digits(-1ull);
size_t i = 0;
int d;
do {
d = digits(i);
cout << i << " has " << d << " digits." << '\n';
i = d < max ? (!i ? 9 : 10 * i - 1) : -1;
cout << i << " has " << digits(i) << " digits." << '\n';
} while (++i);
}
* Everything was tested on a Windows 10 (64-bit) machine using GCC 12.2.0 in Visual Studio Code .
As long as you are mixing C stdio and C++ iostream, you can use the snprintf NULL 0 trick to get the number of digits in the integer representation of the number. Specifically, per man 3 printf If the string exceeds the size parameter provided and is truncated snprintf() will return
... the number of characters (excluding the terminating null byte)
which would have been written to the final string if enough space
had been available.
This allows snprintf() to be called with the str parameter NULL and the size parameter 0, e.g.
int ndigits = snprintf (NULL, 0, "%d", 234567545)
In your case where you simply wish to output the number of digits required for the representation, you can simply output the return, e.g.
#include <iostream>
#include <cstdio>
int main() {
std::cout << "234567545 is " << snprintf (NULL, 0, "%d", 234567545) <<
" characters\n";
}
Example Use/Output
$ ./bin/snprintf_trick
234567545 is 9 characters
note: the downside to using the snprintf() trick is that you must provide the conversion specifier which will limit the number of digits representable. E.g "%d" will limit to int values while "%lld" would allow space for long long values. The C++ approach using std::stringstream while still limited to numeric conversion using the << operator handles the different integer types without manually specifying the conversion. Something to consider.
second note: you shouldn't dangle the "\n" of the end of your sprintf() conversion. Add the new line as part of your output and you don't have to subtract 1 from the length...
I wrote the following code to sum the series (-1)^i*(i/(i+1)). But when I run it I get -1 for any value of n.
Can some one please point out what I am doing wrong? Thank you in advance!
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
int i = 1.0;
int n = 5.0;
for(i=1;i<=n;i++)
sum = (-1)^i*(i/(i+1));
cout << "Sum" <<" = "<< sum << endl;
return 0;
}
Problem #1: The C++ ^ operator isn't the math power operator. It's a bitwise XOR.
You should use pow() instead.
Problem #2:
You are storing floating-point types into an integer type. So the following will result in integer division (truncated division):
i/(i+1)
Problem #3:
You are not actually summing anything up:
sum = ...
should be:
sum += ...
A corrected version of the code is as follows:
double sum = 0;
int i = 1;
int n = 5;
for(i = 1; i <= n; i++)
sum += pow(-1.,(double)i) * ((double)i / (i + 1));
Although you really don't need to use pow in this case. A simple test for odd/even will do.
double sum = 0;
int i = 1;
int n = 5;
for(i = 1; i <= n; i++){
double val = (double)i / (i + 1);
if (i % 2 != 0){
val *= -1.;
}
sum += val;
}
You need too put sum += pow(-1,i)*(i/(i+1));
Otherwise you lose previous result each time.
Use pow function for pow operation.
edit : as said in other post, use double or float instead of int to avoid truncated division.
How about this
((i % 2) == 0 ? 1 : -1)
instead of
std::pow(-1, i)
?
Full answer:
double sum = 0;
int i = 1.0;
int n = 5.0;
for (i = 1; i <= n; ++i) {
signed char sign = ((i % 2) == 0 ? 1 : -1);
sum += sign * (i / (i+1));
}
Few problems:
^ is teh bitwise exclusive or in c++ not "raised to power". Use pow() method.
Remove the dangling opening bracket from the last line
Use ints not floats when assigning to ints.
You seem to have a few things wrong with your code:
using namespace std;
This is not directly related to your problem at hand, but don't ever say using namespace std; It introduces subtle bugs.
int i = 1.0;
int n = 5.0;
You are initializaing integral variables with floating-point constants. Try
int i = 1;
int n = 5;
sum = (-1)^i*(i/(i+1));
You have two problems with this expression. First, the quantity (i/(i+1)) is always zero. Remember dividing two ints rounds the result. Second, ^ doesn't do what you think it does. It is the exclusive-or operator, not the exponentiation operator. Third, ^ binds less tightly than *, so your expression is:
-1 xor (i * (i/(i+1)))
-1 xor (i * 0)
-1 xor 0
-1
^ does not do what you think it does. Also there are some other mistakes in your code.
What it should be:
#include <iostream>
#include <cmath>
int main( )
{
long sum = 0;
int i = 1;
int n = 5;
for( i = 1; i <= n; i++ )
sum += std::pow( -1.f, i ) * ( i / ( i + 1 ) );
std::cout << "Sum = " << sum << std::endl;
return 0;
}
To take a power of a value, use std::pow (see here). Also you can not assign int to a decimal value. For that you need to use float or double.
The aforementioned ^ is a bitwise-XOR, not a mark for an exponent.
Also be careful of Integer Arithmetic as you may get unexpected results. You most likely want to change your variables to either float or double.
There are a few issues with the code:
int sum = 0;
The intermediate results are not integers, this should be a double
int i = 1.0;
Since you will use this in a division, it should be a double, 1/2 is 0 if calculated in integers.
int n = 5.0;
This is an int, not a floating point value, no .0 is needed.
for(i=1;i<=n;i++)
You've already initialized i to 1, why do it again?
sum = (-1)^i*(i/(i+1));
Every iteration you lose the previous value, you should use sum+= 'new values'
Also, you don't need pow to calculate (-1)^i, all this does is switch between +1 and -1 depending on the odd/even status of i. You can do this easier with an if statement or with 2 for's, one for odd i one for even ones... Many choices really.
I have an int that I want to store as a binary string representation. How can this be done?
Try this:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<32> x(23456);
std::cout << x << "\n";
// If you don't want a variable just create a temporary.
std::cout << std::bitset<32>(23456) << "\n";
}
I have an int that I want to first convert to a binary number.
What exactly does that mean? There is no type "binary number". Well, an int is already represented in binary form internally unless you're using a very strange computer, but that's an implementation detail -- conceptually, it is just an integral number.
Each time you print a number to the screen, it must be converted to a string of characters. It just so happens that most I/O systems chose a decimal representation for this process so that humans have an easier time. But there is nothing inherently decimal about int.
Anyway, to generate a base b representation of an integral number x, simply follow this algorithm:
initialize s with the empty string
m = x % b
x = x / b
Convert m into a digit, d.
Append d on s.
If x is not zero, goto step 2.
Reverse s
Step 4 is easy if b <= 10 and your computer uses a character encoding where the digits 0-9 are contiguous, because then it's simply d = '0' + m. Otherwise, you need a lookup table.
Steps 5 and 7 can be simplified to append d on the left of s if you know ahead of time how much space you will need and start from the right end in the string.
In the case of b == 2 (e.g. binary representation), step 2 can be simplified to m = x & 1, and step 3 can be simplified to x = x >> 1.
Solution with reverse:
#include <string>
#include <algorithm>
std::string binary(unsigned x)
{
std::string s;
do
{
s.push_back('0' + (x & 1));
} while (x >>= 1);
std::reverse(s.begin(), s.end());
return s;
}
Solution without reverse:
#include <string>
std::string binary(unsigned x)
{
// Warning: this breaks for numbers with more than 64 bits
char buffer[64];
char* p = buffer + 64;
do
{
*--p = '0' + (x & 1);
} while (x >>= 1);
return std::string(p, buffer + 64);
}
AND the number with 100000..., then 010000..., 0010000..., etc. Each time, if the result is 0, put a '0' in a char array, otherwise put a '1'.
int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;
for(int i = 0; i < numberOfBits; ++i) {
if ((decimal & (0x80000000 >> i)) == 0) {
binary[i] = '0';
} else {
binary[i] = '1';
}
}
binary[numberOfBits] = '\0';
string binaryString(binary);
http://www.phanderson.com/printer/bin_disp.html is a good example.
The basic principle of a simple approach:
Loop until the # is 0
& (bitwise and) the # with 1. Print the result (1 or 0) to the end of string buffer.
Shift the # by 1 bit using >>=.
Repeat loop
Print reversed string buffer
To avoid reversing the string or needing to limit yourself to #s fitting the buffer string length, you can:
Compute ceiling(log2(N)) - say L
Compute mask = 2^L
Loop until mask == 0:
& (bitwise and) the mask with the #. Print the result (1 or 0).
number &= (mask-1)
mask >>= 1 (divide by 2)
I assume this is related to your other question on extensible hashing.
First define some mnemonics for your bits:
const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;
Then you have your number you want to convert to a bit string:
int x = someValue;
You can check if a bit is set by using the logical & operator.
if(x & FIRST_BIT)
{
// The first bit is set.
}
And you can keep an std::string and you add 1 to that string if a bit is set, and you add 0 if the bit is not set. Depending on what order you want the string in you can start with the last bit and move to the first or just first to last.
You can refactor this into a loop and using it for arbitrarily sized numbers by calculating the mnemonic bits above using current_bit_value<<=1 after each iteration.
There isn't a direct function, you can just walk along the bits of the int (hint see >> ) and insert a '1' or '0' in the string.
Sounds like a standard interview / homework type question
Use sprintf function to store the formatted output in the string variable, instead of printf for directly printing. Note, however, that these functions only work with C strings, and not C++ strings.
There's a small header only library you can use for this here.
Example:
std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays "10101"
auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"
auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"
Solution without reverse, no additional copy, and with 0-padding:
#include <iostream>
#include <string>
template <short WIDTH>
std::string binary( unsigned x )
{
std::string buffer( WIDTH, '0' );
char *p = &buffer[ WIDTH ];
do {
--p;
if (x & 1) *p = '1';
}
while (x >>= 1);
return buffer;
}
int main()
{
std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
return 0;
}
This is my best implementation of converting integers(any type) to a std::string. You can remove the template if you are only going to use it for a single integer type. To the best of my knowledge , I think there is a good balance between safety of C++ and cryptic nature of C. Make sure to include the needed headers.
template<typename T>
std::string bstring(T n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}
Use it like so,
std::cout << bstring<size_t>(371) << '\n';
This is the output in my computer(it differs on every computer),
0000000000000000000000000000000000000000000000000000000101110011
Note that the entire binary string is copied and thus the padded zeros which helps to represent the bit size. So the length of the string is the size of size_t in bits.
Lets try a signed integer(negative number),
std::cout << bstring<signed int>(-1) << '\n';
This is the output in my computer(as stated , it differs on every computer),
11111111111111111111111111111111
Note that now the string is smaller , this proves that signed int consumes less space than size_t. As you can see my computer uses the 2's complement method to represent signed integers (negative numbers). You can now see why unsigned short(-1) > signed int(1)
Here is a version made just for signed integers to make this function without templates , i.e use this if you only intend to convert signed integers to string.
std::string bstring(int n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}