Place least significant bits of int into char in C++ -
i find maximally efficient way compute char contains least significant bits of int in c++11. solution must work possible standards-compliant compiler. (i'm using n3290 c++ draft spec, c++11.)
the reason i'm writing fuzz tester, , want check libraries require std::string input. need generate random characters strings. pseudo-random generator i'm using provides ints low bits pretty uniformly random, i'm not sure of exact range. (basically exact range depends on "size of test case" runtime parameter.)
if didn't care working on compiler, simple as:
inline char int2char(int i) { return i; } before dismiss trivial question, consider that:
you don't know whether
charsigned or unsigned type.if
charsigned, conversion unrepresentableintchar"implementation-defined" (§4.7/3). far better undefined, solution i'd need see evidence standard prohibits things converting ints not betweenchar_min,char_max'\0'.reinterpret_castnot permitted between signed , unsigned char (§5.2.10).static_castperforms same conversion in previous point.char c = & 0xff;--though silences compiler warnings--is not correct implementation-defined conversions. in particular,i & 0xffpositive number, in casecsigned quite plausibly not convert negative values ofinegative values ofc.
here solutions work, in of these cases i'm worried won't efficient simple conversion. these seem complicated simple:
using
reinterpret_caston pointer or reference, since can convertunsigned char *orunsigned char &char *orchar &(but @ possible cost of runtime overhead).using union of
char,unsigned char, first assignintunsigned char, extractchar(which again slower).shifting left , right sign-extend int. e.g., if
iint, runningc = ((i << 8 * (sizeof(i) - sizeof(c)) >> 8 * (sizeof(i) - sizeof(c))(but that's inelegant, , if compiler doesn't optimize away shifts, quite slow).
here's minimal working example. goal argue assertions can never fail on compiler, or define alternate int2char in assertions can never fail.
#include <algorithm> #include <cassert> #include <cstdio> #include <cstdlib> using namespace std; constexpr char int2char(int i) { return i; } int main(int argc, char **argv) { (int n = 1; n < min(argc, 127); n++) { char c = -n; int = (atoi(argv[n]) << 8) ^ -n; assert(c == int2char(i)); } return 0; } i've phrased question in terms of c++ because standards easier find on web, equally interested in solution in c. here's mwe in c:
#include <assert.h> #include <stdlib.h> static char int2char(int i) { return i; } int main(int argc, char **argv) { (int n = 1; n < argc && n < 127; n++) { char c = -n; int = (atoi(argv[n]) << 8) ^ -n; assert(c == int2char(i)); } return 0; }
a far better way have array of chars , generate random number pick char array. way 'well behaved' characters; or @ least characters defined badness. if want 256 chars (note 8 bit assumption) create array 256 entries in ('a','b',....'\t','n'.....)
this portable too
Comments
Post a Comment