How to put integer bits in a float? - c++

I have vertices coming in as float_3's. I want to add an integer to them and then ship them out as float_4's. I don't want to convert the integer into a float with the same value, I need the bits to be exactly the same (the integer is a bucket xyz value bit shifted together).
Here is what I tried:
void tagVerts (vector<float_3> &Verts, vector<float_4> &Output) {
int len = Verts.size();
for (int i = 0; i < len; i++) {
Output[i].xyz = Verts[i];
Output[i].w = reinterpret_cast<float>(XYZTag(Verts[i]));
}
}
it says invalid type conversion :/
EDIT:
float_3 and float_4 are from amp.h, as far as I can tell they are just 3 or 4 floats in a struct with a bunch of conversion and assignment helper functions.
XYZTag is as follows:
int XYZTag(float_3 pos) {
pos = pos * mul + add;
int_3 posi (static_cast<int>(pos.x), static_cast<int>(pos.y), static_cast<int>(pos.z));
return((posi.x << 10) + posi.y << 10) + posi.z;
}

You must not interpret the bits of an int as a float as doing so would violate strict aliasing rules and therefore invoke undefined behavior. The correct way to do this is to copy the bits over using memcpy.
#include <cstring>
inline float
int_bits_to_float(const int bits)
{
static_assert(sizeof(int) >= sizeof(float), "too few bits");
float target;
std::memcpy(&target, &bits, sizeof(float));
return target;
}
As terrible a solution as it might seem to be at a first glance, we should really expect the compiler to figure out that this can be optimized down to a few move instructions. GCC does this even at default optimization level.

You cannot reinterpret_cast<> the int directly. The static_cast<> will not do what you want.
To copy the bit pattern to another type, you need something like:
int val = 23;
float bitCopy = *reinterpret_cast<float*>(&val);
Now, for this to work at all, you better have sizeof(float) and sizeof(int) the same.
Further, we'll have to assume you know what you are doing to want this at all.

reinterpret_cast will not reinterpret an int as a float, but it can reinterpret a pointer.
int temp = XYZTag(Verts[i]);
Output[i].w = *reinterpret_cast<float*>(&temp);
// ^ ^ ^
This will stuff the exact bits of your int into the float Output[i].w. It will be your responsibility to ensure that those types are the same size.

Related

Fast bitwise comparison of unaligned bit streams

I have two bit streams A[1..a] and B[1..b], where a is always smaller than b. Now, given an index c in B, I want to know if A matches the area B[c..c+a-1] (assume c+a-1<=b always hold).
I can't just use memcmp because A and B[c..c+a-1] are not necessarily byte-aligned.
So I have a custom function that compares A and B[c..c+a-1] bitwise, where B is encoded within a class that performs bit operations. This is my C++ code:
#include<cstddef>
#include<cstdint>
struct bitstream{
constexpr static uint8_t word_bits = 64;
constexpr static uint8_t word_shift = 6;
const static size_t masks[65];
size_t *B;
inline bool compare_chunk(const void* A, size_t a, size_t c) {
size_t n_words = a / word_bits;
size_t left = c & (word_bits - 1UL);
size_t right = word_bits - left;
size_t cell_i = c >> word_shift;
auto tmp_in = reinterpret_cast<const size_t *>(A);
size_t tmp_data;
//shift every cell in B[c..c+a-1] to compare it against A
for(size_t k=0; k < n_words - 1; k++){
tmp_data = (B[cell_i] >> left) & masks[right];
tmp_data |= (B[++cell_i] & masks[left]) << right;
if(tmp_data != tmp_in[k]) return false;
}
size_t read_bits = (n_words - 1) << word_shift;
return (tmp_in[n_words - 1] & masks[(a-read_bits)]) == read(c + read_bits, c+a-1);
}
inline size_t read(size_t i, size_t j) const{
size_t cell_i = i >> word_shift;
size_t i_pos = (i & (word_bits - 1UL));
size_t cell_j = j >> word_shift;
if(cell_i == cell_j){
return (B[cell_i] >> i_pos) & masks[(j - i + 1UL)];
}else{
size_t right = word_bits-i_pos;
size_t left = 1+(j & (word_bits - 1UL));
return ((B[cell_j] & masks[left]) << right) | ((B[cell_i] >> i_pos) & masks[right]);
}
}
};
const size_t bitstream::masks[65]={0x0,
0x1,0x3, 0x7,0xF,
0x1F,0x3F, 0x7F,0xFF,
0x1FF,0x3FF, 0x7FF,0xFFF,
0x1FFF,0x3FFF, 0x7FFF,0xFFFF,
0x1FFFF,0x3FFFF, 0x7FFFF,0xFFFFF,
0x1FFFFF,0x3FFFFF, 0x7FFFFF,0xFFFFFF,
0x1FFFFFF,0x3FFFFFF, 0x7FFFFFF,0xFFFFFFF,
0x1FFFFFFF,0x3FFFFFFF, 0x7FFFFFFF,0xFFFFFFFF,
0x1FFFFFFFF,0x3FFFFFFFF, 0x7FFFFFFFF,0xFFFFFFFFF,
0x1FFFFFFFFF,0x3FFFFFFFFF, 0x7FFFFFFFFF,0xFFFFFFFFFF,
0x1FFFFFFFFFF,0x3FFFFFFFFFF, 0x7FFFFFFFFFF,0xFFFFFFFFFFF,
0x1FFFFFFFFFFF,0x3FFFFFFFFFFF, 0x7FFFFFFFFFFF,0xFFFFFFFFFFFF,
0x1FFFFFFFFFFFF,0x3FFFFFFFFFFFF, 0x7FFFFFFFFFFFF,0xFFFFFFFFFFFFF,
0x1FFFFFFFFFFFFF,0x3FFFFFFFFFFFFF, 0x7FFFFFFFFFFFFF,0xFFFFFFFFFFFFFF,
0x1FFFFFFFFFFFFFF,0x3FFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,
0x1FFFFFFFFFFFFFFF,0x3FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF}
The function read belongs to the class that wraps B and reads an area of B of most 64 bits.
The code above works, but it seems to be the bottleneck of my application (I run it exhaustively over massive inputs).
Now, my question is: do you know if there is a technique to compare A and B[c..c+a-1] faster?
I know I could use SIMD instructions, but I don't think it will produce a significant improvement as B is encoded in 64-bit cells.
Here are some extra details:
A is usually short (maybe 20 or 30 64-bit cells), but there is not guarantee. It could also be arbitrarily large, although always smaller than B.
I can't make any assumption about A's encoding. It could be uint8_t, uint16_t, uint32_t or uint64_t. That is the reason I pass it as void* to the function.
Link to godbolt with the code above compiling example
Thanks!
A few things you can try:
as noted before, you can't just cast A to size_t*. You either need to go byte-by-byte, or check the beginning and end that's not 8-byte aligned separately
move the declaration of tmp_data inside the loop as a single 'size_t const tmp_data' assignment, refer to B[cell_i] and B[cell_i+1], and increment cell_i in the for statement. That way the compiler can do loop unrolling (at least it can detect that it can much more easily).
finally, if memory is not an issue, then you can keep 8 copies of B (each shifted by a bit to the right), and use the one where B[c] is the beginning of a new byte. Then you can use memcmp (which will presumably give you the fastest code).

C++ update structure offset

when i trying make function to set meshes, then i got error E0137. getMeshes works well.
When i trying to do somethink like
RpMesh* a = header->GetMeshes();
a = newMeshes;
this too not working.
struct RpMeshHeader
{
unsigned int flags;
unsigned short numMeshes;
unsigned short serialNum;
unsigned int totalIndicesInMesh;
unsigned int firstMeshOffset;
RpMesh *getMeshes(void) { return (RpMesh*)(this + 1); }
void setMeshes(RpMesh* newMesh)
{
(RpMesh*)(this + 1)= newMesh;
}
bool isValidMeshId(int meshId)
{
return (meshId != NULL && numMeshes >= meshId);
}
}
Whole file
https://github.com/CrosRoad95/mtasa-blue/blob/f740b0d7410f33ff323cad25bf897725ad44d7d3/Client/sdk/game/RenderWare.h
The error here is quite clear:
void setMeshes(RpMesh* newMesh)
{
(RpMesh*)(this + 1)= newMesh;
}
error: lvalue required as left operand of assignment
the following is not an lvalue and so you cannot assign to it.
(RpMesh*)(this + 1)
The github you linked shows the setMeshes as the following
void setMeshes(RpMesh* newMeshes)
{
RpMesh* meshes = (RpMesh*)(this + 1);
meshes = newMeshes;
}
which is fine in terms of syntax. First you create a pointer meshes to which you assign the address of (this+1) (if this was an array, this+1 would point to the next element in the array) but with a cast!
You cast this hypothetical next element in this array of RpMeashHeader to RpMesh with a C-style cast (which afaik will default to a reinterpret_cast in this case see here for more information)
But has this memory every been allocated? This seems unsafe.

go equivalents of c types

What are the right equivalent of unsigned char or unsigned char* in go? Or am I even doing this right?
I have this C++ class:
class ArcfourPRNG
{
public:
ArcfourPRNG();
void SetKey(unsigned char *pucKeyData, int iKeyLen);
void Reset();
unsigned char Rand();
private:
bool m_bInit;
unsigned char m_aucState0[256];
unsigned char m_aucState[256];
unsigned char m_ucI;
unsigned char m_ucJ;
unsigned char* m_pucState1;
unsigned char* m_pucState2;
unsigned char m_ucTemp;
};
I am trying to rewrite it to go:
type ArcfourPRNG struct {
m_bInit bool
m_aucState0 [256]byte
m_aucState [256]byte
m_ucI, m_ucJ []byte
*m_pucState1 []byte
*m_pucState2 []byte
m_ucTemp []byte
}
func (arc4 *ArcfourPRNG) SetKey(pucKeyData []byte, iKeyLen int) {
func (arc4 *ArcfourPRNG) Reset() {
func (arc4 *ArcfourPRNG) Rand() uint {
Well, I just started with go a few hours ago. So this is still confusing me.
A function
for(i=0; i<256; i++)
{
m_pucState1 = m_aucState0 + i;
m_ucJ += *m_pucState1 + *(pucKeyData+m_ucI);
m_pucState2 = m_aucState0 + m_ucJ;
//Swaping
m_ucTemp = *m_pucState1;
*m_pucState1 = *m_pucState2;
*m_pucState2 = m_ucTemp;
m_ucI = (m_ucI + 1) % iKeyLen;
}
memcpy(m_aucState, m_aucState0, 256); // copy(aucState[:], aucState0) ?
Hopefully this can clear a few things up for you.
For storing raw sequences of bytes, use a slice []byte. If you know exactly how long the sequence will be, you can specify that, e.g. [256]byte but you cannot resize it later.
While Go has pointers, it does not have pointer arithmetic. So you will need to use integers to index into your slices of bytes.
For storing single bytes, byte is sufficient; you don't want a slice of bytes. Where there are pointers in the C++ code used to point to specific locations in the array, you'll simply have an integer index value that selects one element of a slice.
Go strings are not simply sequences of bytes, they are sequences of UTF-8 characters stored internally as runes, which may have different lengths. So don't try to use strings for this algorithm.
To reimplement the algorithm shown, you do not need either pointers or pointer arithmetic at all. Instead of keeping pointers into the byte arrays as you would in C++, you'll use int indexes into the slices.
This is kind of hard to follow since it's virtually all pointer arithmetic. I would want to have a description of the algorithm handy while converting this (and since this is probably a well-known algorithm, that should not be hard to find). I'm not going to do the entire conversion for you, but I'll demonstrate with hopefully a simpler example. This prints each character of a string on a separate line.
C++:
unsigned char *data = "Hello World";
unsigned char *ptr = 0;
for (int i = 0; i < std::strlen(data); i++) {
ptr = i + data;
std::cout << *ptr << std::endl;
}
Go:
data := []byte("Hello World")
for i := 0; i < len(data); i++ {
// The pointer is redundant already
fmt.Println(data[i:i+1])
}
So, learn about Go slices, and when you do reimplement this algorithm you will likely find the code to be somewhat simpler, or at least easier to understand, than its C++ counterpart.

How can I add multiple ints to a character array, then pull them out?

I am trying to place 3 integers(byte size is 4) into a character string byte by byte using c. I then need to "extract" the integers out of the character array so I can do integer operations on them. I have looked around and could not find any solutions to this. I think this will require some type of pointer use or shifting, but I cannot figure out how to write it.
char str[12]="";
int a;
int b;
int c;
int x;
int y;
int z;
a=5;
b=7;
c=12;
I know that an int is 4 bytes. I would like to make it so the str char array has the following data in it.
str = |a1|a2|a3|a4|b1|b2|b3|b4|c1|c2|c3|c4|
*I do not want it like this. str=|'5'|'7'|'12'|
I then need to "extract" the integers out of the character array.
x=str[0-3]; //extracting a
y=str[4-7]; //extracting b
z=str[8-11]; //extracting c
After this, I should be able to write x=y+z and x will be equal to 19.
One way is to treat str as an int array instead:
int* istr = reinterpret_cast<int*>(str)
Then you can use e.g.
istr[0] = a;
istr[1] = b;
istr[2] = c;
and
x = istr[0];
y = istr[1];
z = istr[2];
The question is not well posed so you are getting different answers which may or may not be solving your problem. In my interpretation, here's what you need:
int i1, i2, i3;
char arr[sizeof(i1)+sizeof(i2)+sizeof(i3)];
memcpy(arr, &i1, sizeof(i1));
memcpy(arr+sizeof(i1), &i2, sizeof(i2));
memcpy(arr+sizeof(i1)+sizeof(i2), &i3, sizeof(i3));
Note that I'm being deliberately explicit with using sizeof(i) instead of just "4". It is fairly safe that integers will be 32-bit in whatever environment you are using, but this is safer and strictly speaking more correct.
The easiest solution is to use memcpy:
int nums[sizeof str / sizeof(int)];
std::memcpy(nums, str, sizeof nums);
// Do work on nums here...
The reinterpret_cast approach is undefined behaviour.
Use (void *) to get a pointer to x, byte by byte
for (int i = 0; i < sizeof(int); ++i) {
str[i] = (void *)(&x)[i];
}
This will copy the 4 bytes of x into str, one by one. (void )(&x) casts x as a char array (or void*, same thing), and [i] accesses the i_th byte of the array
then access elements of str the same way.
Do the same with y and z, and don't forget the offset

Shortest way to calculate difference between two numbers?

I'm about to do this in C++ but I have had to do it in several languages, it's a fairly common and simple problem, and this is the last time. I've had enough of coding it as I do, I'm sure there must be a better method, so I'm posting here before I write out the same long winded method in yet another language;
Consider the (lilies!) following code;
// I want the difference between these two values as a positive integer
int x = 7
int y = 3
int diff;
// This means you have to find the largest number first
// before making the subtract, to keep the answer positive
if (x>y) {
diff = (x-y);
} else if (y>x) {
diff = (y-x);
} else if (x==y) {
diff = 0;
}
This may sound petty but that seems like a lot to me, just to get the difference between two numbers. Is this in fact a completely reasonable way of doing things and I'm being unnecessarily pedantic, or is my spidey sense tingling with good reason?
Just get the absolute value of the difference:
#include <cstdlib>
int diff = std::abs(x-y);
Using the std::abs() function is one clear way to do this, as others here have suggested.
But perhaps you are interested in succinctly writing this function without library calls.
In that case
diff = x > y ? x - y : y - x;
is a short way.
In your comments, you suggested that you are interested in speed. In that case, you may be interested in ways of performing this operation that do not require branching. This link describes some.
#include <cstdlib>
int main()
{
int x = 7;
int y = 3;
int diff = std::abs(x-y);
}
All the existing answers will overflow on extreme inputs, giving undefined behaviour. #craq pointed this out in a comment.
If you know that your values will fall within a narrow range, it may be fine to do as the other answers suggest, but to handle extreme inputs (i.e. to robustly handle any possible input values), you cannot simply subtract the values then apply the std::abs function. As craq rightly pointed out, the subtraction may overflow, causing undefined behaviour (consider INT_MIN - 1), and the std::abs call may also cause undefined behaviour (consider std::abs(INT_MIN)). It's no better to determine the min and max of the pair and to then perform the subtraction.
More generally, a signed int is unable to represent the maximum difference between two signed int values. The unsigned int type should be used for the output value.
I see 3 solutions. I've used the explicitly-sized integer types from stdint.h here, to close the door on uncertainties like whether long and int are the same size and range.
Solution 1. The low-level way.
// I'm unsure if it matters whether our target platform uses 2's complement,
// due to the way signed-to-unsigned conversions are defined in C and C++:
// > the value is converted by repeatedly adding or subtracting
// > one more than the maximum value that can be represented
// > in the new type until the value is in the range of the new type
uint32_t difference_int32(int32_t i, int32_t j) {
static_assert(
(-(int64_t)INT32_MIN) == (int64_t)INT32_MAX + 1,
"Unexpected numerical limits. This code assumes two's complement."
);
// Map the signed values across to the number-line of uint32_t.
// Preserves the greater-than relation, such that an input of INT32_MIN
// is mapped to 0, and an input of 0 is mapped to near the middle
// of the uint32_t number-line.
// Leverages the wrap-around behaviour of unsigned integer types.
// It would be more intuitive to set the offset to (uint32_t)(-1 * INT32_MIN)
// but that multiplication overflows the signed integer type,
// causing undefined behaviour. We get the right effect subtracting from zero.
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
const uint32_t ret = (i_u > j_u) ? (i_u - j_u) : (j_u - i_u);
return ret;
}
I tried a variation on this using bit-twiddling cleverness taken from https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax but modern code-generators seem to generate worse code with this variation. (I've removed the static_assert and the comments.)
uint32_t difference_int32(int32_t i, int32_t j) {
const uint32_t offset = (uint32_t)0 - (uint32_t)(INT32_MIN);
const uint32_t i_u = (uint32_t)i + offset;
const uint32_t j_u = (uint32_t)j + offset;
// Surprisingly it helps code-gen in MSVC 2019 to manually factor-out
// the common subexpression. (Even with optimisation /O2)
const uint32_t t = (i_u ^ j_u) & -(i_u < j_u);
const uint32_t min = j_u ^ t; // min(i_u, j_u)
const uint32_t max = i_u ^ t; // max(i_u, j_u)
const uint32_t ret = max - min;
return ret;
}
Solution 2. The easy way. Avoid overflow by doing the work using a wider signed integer type. This approach can't be used if the input signed integer type is the largest signed integer type available.
uint32_t difference_int32(int32_t i, int32_t j) {
return (uint32_t)std::abs((int64_t)i - (int64_t)j);
}
Solution 3. The laborious way. Use flow-control to work through the different cases. Likely to be less efficient.
uint32_t difference_int32(int32_t i, int32_t j)
{ // This static assert should pass even on 1's complement.
// It's just about impossible that int32_t could ever be capable of representing
// *more* values than can uint32_t.
// Recall that in 2's complement it's the same number, but in 1's complement,
// uint32_t can represent one more value than can int32_t.
static_assert( // Must use int64_t to subtract negative number from INT32_MAX
((int64_t)INT32_MAX - (int64_t)INT32_MIN) <= (int64_t)UINT32_MAX,
"Unexpected numerical limits. Unable to represent greatest possible difference."
);
uint32_t ret;
if (i == j) {
ret = 0;
} else {
if (j > i) { // Swap them so that i > j
const int32_t i_orig = i;
i = j;
j = i_orig;
} // We may now safely assume i > j
uint32_t magnitude_of_greater; // The magnitude, i.e. abs()
bool greater_is_negative; // Zero is of course non-negative
uint32_t magnitude_of_lesser;
bool lesser_is_negative;
if (i >= 0) {
magnitude_of_greater = i;
greater_is_negative = false;
} else { // Here we know 'lesser' is also negative, but we'll keep it simple
// magnitude_of_greater = -i; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_greater = (uint32_t)0 - (uint32_t)i;
greater_is_negative = true;
}
if (j >= 0) {
magnitude_of_lesser = j;
lesser_is_negative = false;
} else {
// magnitude_of_lesser = -j; // DANGEROUS, overflows if i == INT32_MIN.
magnitude_of_lesser = (uint32_t)0 - (uint32_t)j;
lesser_is_negative = true;
}
// Finally compute the difference between lesser and greater
if (!greater_is_negative && !lesser_is_negative) {
ret = magnitude_of_greater - magnitude_of_lesser;
} else if (greater_is_negative && lesser_is_negative) {
ret = magnitude_of_lesser - magnitude_of_greater;
} else { // One negative, one non-negative. Difference is sum of the magnitudes.
// This will never overflow.
ret = magnitude_of_lesser + magnitude_of_greater;
}
}
return ret;
}
Well it depends on what you mean by shortest. The fastet runtime, the fastest compilation, the least amount of lines, the least amount of memory. I'll assume you mean runtime.
#include <algorithm> // std::max/min
int diff = std::max(x,y)-std::min(x,y);
This does two comparisons and one operation (this one is unavoidable but could be optimized through certain bitwise operations with specific cases, compiler might actually do this for you though). Also if the compiler is smart enough it could do only one comparison and save the result for the other comparison. E.g if X>Y then you know from the first comparison that Y < X but I'm not sure if compilers take advantage of this.