Converting a double to an std::bitset - c++11

I have a double that I would like to convert to an std::bitset<64>. How can I do that?

You could cast the pointer to the double variable to unsigned long long, derefence it again and use that as argument for the constructor
double d = 0;
std::bitset<64> b(*(reinterpret_cast<unsigned long long*>(&d)))
But that's not very beautiful.
Here is a approach with a union:
union DoubleToLongLong {
double d;
long long ll;
};
...
DoubleToLongLong dtll;
dtll.d = 3.4;
std::bitset<64> b(dtll.ll);
...
And because unions can have constructors also this is possible:
union DoubleToLongLong {
double d;
long long ll;
DoubleToLongLong(double _d) : d(_d) {}
};
...
std::bitset<64> b(DoubleToLongLong(3.4).ll);
...

constexpr auto BITS = sizeof(double) * CHAR_BIT;
std::bitset<BITS> to_bitset(double d) {
auto bytes = reinterpret_cast<unsigned char*>(&d);
std::bitset<BITS> bits;
for (std::size_t i = 0; i < sizeof(d); ++i) {
for (std::size_t j = 0; j < CHAR_BIT; ++j) {
bits[i * CHAR_BIT + j] = (bytes[i] >> j) & 1;
}
}
return bits;
}

Related

how to fastly find array which include some numbers(1~255)?

I want to solve some algorithm problem.
Could you suggest any algorithms working more fast?
*Problem summary
- Find same array of key[200] is same as source array KEY[200]
- Each element of KEY[200] array is random numbers range 1~255
- only 2 file are given.
- You must implement just function find_array() of user_code.cpp
- It is not allowed to edit any other things
- You can use check() function for finding array
- test case is 50, time limit is 10 sec for 50 test case, memory limit is 256MB.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void find_array(unsigned char key[200]);
unsigned char KEY[200];
int check(unsigned char key[200])
{
int pos = 0;
int equal = 0;
for (int c = 0; c < 200; c++)
{
if (key[c] == KEY[c])
pos++;
}
for (int c1 = 0; c1 < 200; c1++)
{
for (int c2 = 0; c2 < 200; c2++)
{
if(key[c1] == KEY[c2])
equal++;
}
}
return pos * 256 + equal;
}
int main()
{
for (int t = 0; t < 1; t++) //test case 50개
{
for (int i = 0; i < 200; i++)
{
KEY[i] = rand() % 255 + 1; //1~255
}
unsigned char key[200] = { 0, };
find_array(key); //you must implement this function
}
return 0;
}
//user_code.cpp
extern int check(unsigned char key[200]);
//you must implement this function
//below is my code take a long time(about 2sec for each case)
void find_array(unsigned char key[200])
{
unsigned char temp[200];
int result, pos, equal;
for (int k = 0; k < 200; k++)
temp[k] = 0;
for (int i = 0; i < 200; i++)
{
for (int val = 1; val <= 255; val++)
{
temp[i] = val;
result = check(temp);
equal = result % 256;
pos = (result - equal) / 256;
if (pos >= 1)
{
key[i] = val;
temp[i] = 0;
break;
}
}
}
}

Array by value multiplication memory leak in c++

I'm having some trouble with multiplying an array (char array in this particular case) by a value.
My code looks like this:
char* tab1 = copy("11");
char t = '2';
int length = strlen(tab1) + 2;
char*result = populate('0', length);
int p_length = strlen(tab1);
for (int j = p_length - 1; j >= 0; j--) {
char* tmp = multiply_chars(tab1[j], t);
v_shove(tmp, j);
char* tmp2 = add_tables(result, tmp);
delete[] result;
result = tmp2;
delete[] tmp;
}
cout << result << endl;
delete[] result;
delete[] tab1;
None of the methods used (that's populate, multiply_chars and add_tables) causes a leak when ran in an infinite loop. I've narrowed the leak to the
char* tmp2 = add_tables(result, tmp);
delete[] result;
result = tmp2;
part, but have no idea why it would happen.
I check for leaks by running snippets in an infinite loop and checking memory usage.
Any help would be appreciated! If need be I'll post the code of the methods used, but decided not to for the sake of brevity here. They all return new cstrings. Also, the t2 variable is there from when I was checking the array by array multiplication, which also leaked - decided to do array by value multiplication first.
(Now, to be completely honest this is one of the methods required for a school project, but it's such a miniscule part of it, that I thought it wouldn't hurt if I asked - the teacher isn't really big on helping with particular code problems)
The functions are:
char * add_tables(const char * table1, const char * table2)
{
char* tmp1 = get_string_trailing("0",table1);
char* tmp2 = get_string_trailing("0", table2);
int l1 = strlen(tmp1), l2 = strlen(tmp2);
if (l1 != l2) {
if (l1 > l2) {
char* t = resize_string(tmp2, l1 - l2, '0');
delete[] tmp2;
tmp2 = t;
}
else {
char* t = resize_string(tmp1, l2 - l1, '0');
delete[] tmp1;
tmp1 = t;
}
}
int length = strlen(tmp1) + 2;
char*result = new char[length];
result[length - 1] = 0;
int buffer = 0;
for (int i = length - 2; i > 0; i--) {
int t = buffer + (tmp1[i-1]-'0') + (tmp2[i-1]-'0');
result[i] = (t% 10)+'0';
buffer = (t - (t % 10))/10;
}
result[0] = buffer + '0';
char* t = get_string_trailing("0", result);
delete[]result;
result = t;
delete[]tmp1;
delete[]tmp2;
return result;
}
void v_shove(char *&c, int i)
{
char* tmp = shove(c, i);
delete[] c;
c = tmp;
}
char * populate(const char populator, int length)
{
char* result = new char[length + 1];
result[length] = 0;
for (int i = 0; i < length; i++) {
result[i] = populator;
}
return result;
}
char * multiply_chars(const char c1,const char c2)
{
char*result = new char[3];
result[2] = 0;
char tmp1 = c1 - '0', tmp2 = c2 - '0';
result[1] = (tmp1*tmp2 % 10) + '0';
result[0] = (tmp1*tmp2 - (tmp1*tmp2 % 10)) / 10 + '0';
char* r = get_string_trailing("0", result);
delete[] result;
result = r;
return result;
}
int get_length_trailing(const char * ignore,const char * table)
{
int length = 0;
int i = 0;
bool flag = true;
while (i < strlen(table)) {
if (flag) {
for (int j = 0; j < strlen(ignore); j++)
if (table[i] == ignore[j])goto BREAKPOINT;
}
flag = false;
length++;
BREAKPOINT:i++;
}
return length;
}
char * get_string_trailing(const char * ignore,const char * table)
{
int result_length = get_length_trailing(ignore, table);
char* result = new char[result_length + 1];
int counter = 0;
int i = 0;
bool flag = true;
while (i < strlen(table)) {
if (flag)
for (int j = 0; j < strlen(ignore); j++)
if (table[i] == ignore[j])goto BREAKPOINT;
flag = false;
result[counter] = table[i];
counter++;
BREAKPOINT:i++;
}
result[result_length] = 0;
if (result_length == 0) return copy("0");
return result;
}
char * shove(const char * table1, int index)
{
char*result = "0";
int length = strlen(table1) + index + 1;
result = new char[length];
result[length - 1] = 0;
if (index > 0) {
for (int i = 0; i < strlen(table1); i++)
result[i] = table1[i];
for (int i = 0; i < index; i++)
result[strlen(table1) + i] = '0';
}
else {
for (int i = 0; i < strlen(result); i++)
result[i] = table1[i];
}
char* t = get_string_trailing("0", result);
delete[] result;
result = t;
return result;
}
There is at least a memory leak in get_string_trailing: if result_length is zero, you return a copy and do not delete result. There are also confusions between "string" (such as "0") and 'char': with double quotes, the terminating string character (\0) is automatically appended to the string, while simple quotes only define a character. So "0" is made of 2 char in memory and can not be stored in a pointer (undefined behavior, overwriting memory).
To summarize: here you are writing C, not learning C++. If you have to deal with C strings (you are writing a low-level pilot in C or your professor still doesn't understand that C and C++ are different languages), at least use the functions of the string.h (in C) / cstring (in C++) header to minimize the chance of memory leak or undefined behavior. If you do not have to use C strings, use std::string and the string manipulation tools of the standard library. Your work will be much easier, and your code much less vulnerable to bugs:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string tab1("11")
string t("2") // never use the single quotes for a string
cout << stoi(tab1) * stoi(t) << endl;
return;
}
That's it!

Mapping a large number to a unique number using MOD operation

Let the Roots of a first degree polynomial( Q(x) ) be x0 = -b/a. Since the range of the variable a and b is large, x0 can be large as well for it to be stored in a variable(x0).
so, it is converted to some unique number using some operation with mod
int x0 = mul(mod - b, rev(a));
problem link: hackerank problem
Can someone please explain how this line of code works and the math behind this operation?
the whole code-
#include <bits/stdc++.h>
using namespace std;
#define forn(i,n) for (int i = 0; i < int(n); ++i)
typedef long long ll;
const int inf = int(1e9) + int(1e5);
const ll infl = ll(2e18) + ll(1e10);
const int mod = 1e9 + 7;
int udd(int &a, int b) {
a += b;
if (a >= mod)
a -= mod;
return a;
}
int add(int a, int b) {
return udd(a, b);
}
int mul(ll a, ll b) {
return a * b % mod;
}
//============didnt understand this step
int bin(int a, int d) {
int b = 1;
while (d) {
if (d & 1)
b = mul(b, a);
d >>= 1;
a = mul(a, a);
}
return b;
}
int rev(int a) {
assert(a != 0);
return bin(a, mod - 2);
}
const int maxn = 100100;
int px[maxn];
int c[maxn];
struct Fenwick {
int a[maxn];
int t[maxn];
void set(int pos, int val) {
int delta = add(val, mod - a[pos]);
a[pos] = val;
delta = mul(delta, px[pos]);
for (int i = pos; i < maxn; i |= i + 1) {
udd(t[i], delta);
}
}
int get(int r) {
int res = 0;
for (int i = r - 1; i >= 0; i = (i & (i + 1)) - 1)
udd(res, t[i]);
return res;
}
int get(int l, int r) {
return add(get(r), mod - get(l));
}
} fw;
int main() {
#ifdef LOCAL
assert(freopen("test.in", "r", stdin));
#endif
int n, a, b, q;
cin >> n >> a >> b >> q;
//========what does this line do?
int x0 = mul(mod - b, rev(a));
px[0] = 1;
for (int i = 1; i < n; ++i)
px[i] = mul(px[i - 1], x0);
forn (i, n) {
cin >> c[i];
fw.set(i, c[i]);
}
forn (i, q) {
int t, a, b;
cin >> t >> a >> b;
if (t == 1) {
fw.set(a, b);
} else {
++b;
int s = fw.get(a, b);
if (x0 == 0)
s = fw.a[a];
cout << (s == 0 ? "Yes" : "No") << '\n';
}
}
}
bin is the halving-and-squaring implementation for the (in this case modular) power function a^d % mod, so that the modular inverse in rev can be computed via the little theorem of Fermat.

expression must have arithmetic or unscoped enum type

This is my first try at a method without input. Here is the code:
int factorial(int a)
{
int i = 1, result = 1;
while (i <= a)
{
result = result * i;
i++;
}
return result;
}
int double_factorial(int a)
{
int i = 2, result = 1;
while (i <= a)
{
result = result * i;
i = i + 2;
}
return result;
}
long double pi()
{
unsigned long int n = 4294967295;
unsigned long int i = 0;
long double result = 0;
while (i <= n)
{
result = result + (factorial(i) / double_factorial(2 * i + 1));
i++;
}
long double pi = result * 2;
return pi;
}
long double circumference_circle_input_radius(double r)
{
long double C = 2.0 * pi * r; //error: 'pi' expression must have arithmetic or unscoped enum type.
}
When I try to use method "pi" in this, the error appeared. I dont understand what the error means, so it is quite hard to understand the problem and debug it.
pi is a function, not a variable. To call it in an expression, you need to use parentheses:
long double C = 2.0 * pi() * r;
^^
Without the parentheses, the compiler thinks you're trying to multiply the function itself by 2, which isn't an operation that makes any sense.

The most efficient way to remove all characters in the 1st string from the 2nd string?

I was asked about this question. I can only think of a O(nm) algorithm if n is the length of the 1st string and m is the length of the 2nd string.
Well, you can do it in O(n + m). Just create a reference table showing whether character exists in first string. Something like this (pseudo-code in no particular language)
// fill the table
for (int i = 0; i < a.length; ++i) {
characterExists[a[i]] = true;
}
// iterate over second string
for (int i = 0; i < b.length; ++i) {
if !characterExists[b[i]] {
// remove char (or do whatever else you want)
}
}
Have you checked out the Boyer-Moore String Search Algorithm?
The worst-case to find all occurrences
in a text needs approximately 3*N
comparisons, hence the complexity is
O(n), regardless whether the text
contains a match or not. This
proof took some years to determine. In
the year the algorithm was devised,
1977, the maximum number of
comparisons was shown to be no more
than 6*N; in 1980 it was shown to be
no more than 4*N, until Cole's result
in Sep 1991.
C implementation:
#include <limits.h>
#include <string.h>
#define ALPHABET_SIZE (1 << CHAR_BIT)
static void compute_prefix(const char* str, size_t size, int result[size]) {
size_t q;
int k;
result[0] = 0;
k = 0;
for (q = 1; q < size; q++) {
while (k > 0 && str[k] != str[q])
k = result[k-1];
if (str[k] == str[q])
k++;
result[q] = k;
}
}
static void prepare_badcharacter_heuristic(const char *str, size_t size,
int result[ALPHABET_SIZE]) {
size_t i;
for (i = 0; i < ALPHABET_SIZE; i++)
result[i] = -1;
for (i = 0; i < size; i++)
result[(size_t) str[i]] = i;
}
void prepare_goodsuffix_heuristic(const char *normal, size_t size,
int result[size + 1]) {
char *left = (char *) normal;
char *right = left + size;
char reversed[size+1];
char *tmp = reversed + size;
size_t i;
/* reverse string */
*tmp = 0;
while (left < right)
*(--tmp) = *(left++);
int prefix_normal[size];
int prefix_reversed[size];
compute_prefix(normal, size, prefix_normal);
compute_prefix(reversed, size, prefix_reversed);
for (i = 0; i <= size; i++) {
result[i] = size - prefix_normal[size-1];
}
for (i = 0; i < size; i++) {
const int j = size - prefix_reversed[i];
const int k = i - prefix_reversed[i]+1;
if (result[j] > k)
result[j] = k;
}
}
/*
* Boyer-Moore search algorithm
*/
const char *boyermoore_search(const char *haystack, const char *needle) {
/*
* Calc string sizes
*/
size_t needle_len, haystack_len;
needle_len = strlen(needle);
haystack_len = strlen(haystack);
/*
* Simple checks
*/
if(haystack_len == 0)
return NULL;
if(needle_len == 0)
return haystack;
/*
* Initialize heuristics
*/
int badcharacter[ALPHABET_SIZE];
int goodsuffix[needle_len+1];
prepare_badcharacter_heuristic(needle, needle_len, badcharacter);
prepare_goodsuffix_heuristic(needle, needle_len, goodsuffix);
/*
* Boyer-Moore search
*/
size_t s = 0;
while(s <= (haystack_len - needle_len))
{
size_t j = needle_len;
while(j > 0 && needle[j-1] == haystack[s+j-1])
j--;
if(j > 0)
{
int k = badcharacter[(size_t) haystack[s+j-1]];
int m;
if(k < (int)j && (m = j-k-1) > goodsuffix[j])
s+= m;
else
s+= goodsuffix[j];
}
else
{
return haystack + s;
}
}
/* not found */
return NULL;
}

Resources