Change all accented letters to normal letters in C++ - c++
The question
How can you change all accented letters to normal letters in C++ (or in C)?
By that, I mean something like eéèêaàäâçc would become eeeeaaaacc.
What I've already tried
I've tried just parsing the string manually and replacing each one of them one by one, but I was thinking there has to be a better/simpler way that I am not aware of (that would garantee I do not forget any accented letter).
I am wondering if there is already a map somewhere in the standard library or if all the accented characters can easily be mapped to the "normal" letter using some mathematic function (ex. floor(charCode-131/5) + 61)).
char* removeAccented( char* str ) {
char *p = str;
while ( (*p)!=0 ) {
const char*
// "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
tr = "AAAAAAECEEEEIIIIDNOOOOOx0UUUUYPsaaaaaaeceeeeiiiiOnooooo/0uuuuypy";
unsigned char ch = (*p);
if ( ch >=192 ) {
(*p) = tr[ ch-192 ];
}
++p; // http://stackoverflow.com/questions/14094621/
}
return str;
}
You should first define what you mean by "accented letters" what has to be done is largely different if what you have is say some extended 8 bits ASCII with a national codepage for codes above 128, or say some utf8 encoded string.
However you should have a look at libicu which provide what is necessary for good unicode based accented letters manipulation.
But it won't solve all problems for you. For instance what should you do if you get some chinese or russian letter ? What should you do if you get the Turkish uppercase I with point ? Remove the point on this "I" ? Doing so it would change the meaning of the text... etc. This kind of problems are endless with unicode. Even conventional sorting order depends of the country...
I know it only in theory. Basically, you perform Unicode normalization, then some decomposition, purge all diacritics, and recompose again.
Assuming the values are just chars, I'd create an array with the desired target values and then just replace each character with the corresponding member in the array:
char replacement[256];
int n(0);
std::generate_n(replacement, 256, [=]() mutable -> unsigned char { return n++; });
replacement[static_cast<unsigned char>('é')] = 'e';
// ...
std::transform(s.begin(), s.end(), s.begin(),
[&](unsigned char c){ return replacement[c]; });
Since the question is also tagged with C: when using C you'd need to create suitable loops to do the same operations but conceptually it would just same way. Similarily, if you can't use C++ 2011, you'd just use suitable function objects instead of the lambda functions.
Obviously, the replacement array can be set up just once and using a smarter approach than what is outlined above. However, the principle should work. If you need to replace Unicode characters thing become a bit more interesting, though: For one, the array would be fairly large and in addition the character may need multiple words to be changed.
Here is what you can do using ISO/IEC 8859-1 (ASCII-based standard character encoding):
if code range is from 192 - 197 replace with A
if code range is from 224 - 229 replace with a
if code range is from 200 - 203 replace with E
if code range is from 232 - 235 replace with e
if code range is from 204 - 207 replace with I
if code range is from 236 - 239 replace with i
if code range is from 210 - 214 replace with O
if code range is from 242 - 246 replace with o
if code range is from 217 - 220 replace with U
if code range is from 249 - 252 replace with u
Supposing x is the code of the number, perform the following for capital letters:
y = floor((x - 192) / 6)
if y <= 2 then z = ((y + 1) * 4) + 61 else z = (y * 6) + 61
Perform the following for small letters:
y = floor((x - 224) / 6)
if y <= 2 then z = ((y + 1) * 4) + 93 else z = (y * 6) + 93
The final answer z is the ASCII code of the required alphabet.
Note that this method works only if you are using ISO/IEC 8859-1.
I am afraid there is no easy way around here.
In application I work on this was solved by using internal codepage tables, each codepage table (like 1250, 1251, 1252, etc) contained actual codepage letter and non-diacritic equivalent. Tables were auto generated using c#, it contains some classes that really make that easy (with some heuristics actually), also java allows to implement it quicly.
This was actually for multibyte data with codepages, but it could be used for UNICODE strings (by just searching all tables for given unicode letter).
My use case was needing to do a case-insensitive sort a long list of strings, where some of the strings might have diacriticals. So for instance I wanted "Añasco Municipio" to come right before "Anchorage Municipality", instead of coming right before "Abbeville County" as it was doing with a naive comparison.
My strings are encoded in UTF-8, but there's a chance that they might contain some extended ascii characters instead of proper UTF-8 Unicode. I could have promoted all strings to UTF-8, and then used a library that could do UTF-8 string comparison, but I wanted to have full control both for speed and for deciding exactly how diacritical characters are mapped to non-diacritical characters. (My choices include things like treating the masculine ordinal indicator as "o", and treating the copyright character as c.)
The "two-byte" codes below are UTF-8 sequences. The "one-byte" codes are extended ascii.
This is where I got the codes:
http://www.ascii-code.com/
http://www.endmemo.com/unicode/unicodeconverter.php
void SimplifyStringForSorting( string *s, bool changeToLowerCase )
{
// C0 C1 C2 C3 C4 C5 E0 E1 E2 E3 E4 E5 AA // one-byte codes for "a"
// C3 80 C3 81 C3 82 C3 83 C3 84 C3 85 C3 A0 C3 A1 C3 A2 C3 A3 C3 A4 C3 A5 C2 AA // two-byte codes for "a"
// C8 C9 CA CB E8 E9 EA EB // one-byte codes for "e"
// C3 88 C3 89 C3 8A C3 8B C3 A8 C3 A9 C3 AA C3 AB // two-byte codes for "e"
// CC CD CE CF EC ED EE EF // one-byte codes for "i"
// C3 8C C3 8D C3 8E C3 8F C3 AC C3 AD C3 AE C3 AF // two-byte codes for "i"
// D2 D3 D4 D5 D6 F2 F3 F4 F5 F6 BA // one-byte codes for "o"
// C3 92 C3 93 C3 94 C3 95 C3 96 C3 B2 C3 B3 C3 B4 C3 B5 C3 B6 C2 BA // two-byte codes for "o"
// D9 DA DB DC F9 FA FB FC // one-byte codes for "u"
// C3 99 C3 9A C3 9B C3 9C C3 B9 C3 BA C3 BB C3 BC // two-byte codes for "u"
// A9 C7 E7 // one-byte codes for "c"
// C2 A9 C3 87 C3 A7 // two-byte codes for "c"
// D1 F1 // one-byte codes for "n"
// C3 91 C3 B1 // two-byte codes for "n"
// AE // one-byte codes for "r"
// C2 AE // two-byte codes for "r"
// DF // one-byte codes for "s"
// C3 9F // two-byte codes for "s"
// 8E 9E // one-byte codes for "z"
// C5 BD C5 BE // two-byte codes for "z"
// 9F DD FD FF // one-byte codes for "y"
// C5 B8 C3 9D C3 BD C3 BF // two-byte codes for "y"
int n = s->size();
int pos = 0;
for ( int i = 0 ; i < n ; i++, pos++ )
{
unsigned char c = (unsigned char)s->at( i );
if ( c >= 0x80 )
{
if ( i < ( n - 1 ) && (unsigned char)s->at( i + 1 ) >= 0x80 )
{
unsigned char c2 = SimplifyDoubleCharForSorting( c, (unsigned char)s->at( i + 1 ), changeToLowerCase );
if ( c2 < 0x80 )
{
s->at( pos ) = c2;
i++;
}
else
{
// s->at( pos ) = SimplifySingleCharForSorting( c, changeToLowerCase );
// if it's a double code we don't recognize, skip both characters;
// this does mean that we lose the chance to handle back-to-back extended ascii characters
// but we'll assume that is less likely than a unicode "combining character" or other
// unrecognized unicode character for data
i++;
}
}
else
{
unsigned char c2 = SimplifySingleCharForSorting( c, changeToLowerCase );
if ( c2 < 0x80 )
{
s->at( pos ) = c2;
}
else
{
// skip unrecognized single-byte codes
pos--;
}
}
}
else
{
if ( changeToLowerCase && c >= 'A' && c <= 'Z' )
{
s->at( pos ) = c + ( 'a' - 'A' );
}
else
{
s->at( pos ) = c;
}
}
}
if ( pos < n )
{
s->resize( pos );
}
}
unsigned char SimplifyDoubleCharForSorting( unsigned char c1, unsigned char c2, bool changeToLowerCase )
{
// C3 80 C3 81 C3 82 C3 83 C3 84 C3 85 C3 A0 C3 A1 C3 A2 C3 A3 C3 A4 C3 A5 C2 AA // two-byte codes for "a"
// C3 88 C3 89 C3 8A C3 8B C3 A8 C3 A9 C3 AA C3 AB // two-byte codes for "e"
// C3 8C C3 8D C3 8E C3 8F C3 AC C3 AD C3 AE C3 AF // two-byte codes for "i"
// C3 92 C3 93 C3 94 C3 95 C3 96 C3 B2 C3 B3 C3 B4 C3 B5 C3 B6 C2 BA // two-byte codes for "o"
// C3 99 C3 9A C3 9B C3 9C C3 B9 C3 BA C3 BB C3 BC // two-byte codes for "u"
// C2 A9 C3 87 C3 A7 // two-byte codes for "c"
// C3 91 C3 B1 // two-byte codes for "n"
// C2 AE // two-byte codes for "r"
// C3 9F // two-byte codes for "s"
// C5 BD C5 BE // two-byte codes for "z"
// C5 B8 C3 9D C3 BD C3 BF // two-byte codes for "y"
if ( c1 == 0xC2 )
{
if ( c2 == 0xAA ) { return 'a'; }
if ( c2 == 0xBA ) { return 'o'; }
if ( c2 == 0xA9 ) { return 'c'; }
if ( c2 == 0xAE ) { return 'r'; }
}
if ( c1 == 0xC3 )
{
if ( c2 >= 0x80 && c2 <= 0x85 ) { return changeToLowerCase ? 'a' : 'A'; }
if ( c2 >= 0xA0 && c2 <= 0xA5 ) { return 'a'; }
if ( c2 >= 0x88 && c2 <= 0x8B ) { return changeToLowerCase ? 'e' : 'E'; }
if ( c2 >= 0xA8 && c2 <= 0xAB ) { return 'e'; }
if ( c2 >= 0x8C && c2 <= 0x8F ) { return changeToLowerCase ? 'i' : 'I'; }
if ( c2 >= 0xAC && c2 <= 0xAF ) { return 'i'; }
if ( c2 >= 0x92 && c2 <= 0x96 ) { return changeToLowerCase ? 'o' : 'O'; }
if ( c2 >= 0xB2 && c2 <= 0xB6 ) { return 'o'; }
if ( c2 >= 0x99 && c2 <= 0x9C ) { return changeToLowerCase ? 'u' : 'U'; }
if ( c2 >= 0xB9 && c2 <= 0xBC ) { return 'u'; }
if ( c2 == 0x87 ) { return changeToLowerCase ? 'c' : 'C'; }
if ( c2 == 0xA7 ) { return 'c'; }
if ( c2 == 0x91 ) { return changeToLowerCase ? 'n' : 'N'; }
if ( c2 == 0xB1 ) { return 'n'; }
if ( c2 == 0x9F ) { return 's'; }
if ( c2 == 0x9D ) { return changeToLowerCase ? 'y' : 'Y'; }
if ( c2 == 0xBD || c2 == 0xBF ) { return 'y'; }
}
if ( c1 == 0xC5 )
{
if ( c2 == 0xBD ) { return changeToLowerCase ? 'z' : 'Z'; }
if ( c2 == 0xBE ) { return 'z'; }
if ( c2 == 0xB8 ) { return changeToLowerCase ? 'y' : 'Y'; }
}
return c1;
}
unsigned char SimplifySingleCharForSorting( unsigned char c, bool changeToLowerCase )
{
// C0 C1 C2 C3 C4 C5 E0 E1 E2 E3 E4 E5 AA // one-byte codes for "a"
// C8 C9 CA CB E8 E9 EA EB // one-byte codes for "e"
// CC CD CE CF EC ED EE EF // one-byte codes for "i"
// D2 D3 D4 D5 D6 F2 F3 F4 F5 F6 BA // one-byte codes for "o"
// D9 DA DB DC F9 FA FB FC // one-byte codes for "u"
// A9 C7 E7 // one-byte codes for "c"
// D1 F1 // one-byte codes for "n"
// AE // one-byte codes for "r"
// DF // one-byte codes for "s"
// 8E 9E // one-byte codes for "z"
// 9F DD FD FF // one-byte codes for "y"
if ( ( c >= 0xC0 && c <= 0xC5 ) || ( c >= 0xE1 && c <= 0xE5 ) || c == 0xAA )
{
return ( ( c >= 0xC0 && c <= 0xC5 ) && !changeToLowerCase ) ? 'A' : 'a';
}
if ( ( c >= 0xC8 && c <= 0xCB ) || ( c >= 0xE8 && c <= 0xEB ) )
{
return ( c > 0xCB || changeToLowerCase ) ? 'e' : 'E';
}
if ( ( c >= 0xCC && c <= 0xCF ) || ( c >= 0xEC && c <= 0xEF ) )
{
return ( c > 0xCF || changeToLowerCase ) ? 'i' : 'I';
}
if ( ( c >= 0xD2 && c <= 0xD6 ) || ( c >= 0xF2 && c <= 0xF6 ) || c == 0xBA )
{
return ( ( c >= 0xD2 && c <= 0xD6 ) && !changeToLowerCase ) ? 'O' : 'o';
}
if ( ( c >= 0xD9 && c <= 0xDC ) || ( c >= 0xF9 && c <= 0xFC ) )
{
return ( c > 0xDC || changeToLowerCase ) ? 'u' : 'U';
}
if ( c == 0xA9 || c == 0xC7 || c == 0xE7 )
{
return ( c == 0xC7 && !changeToLowerCase ) ? 'C' : 'c';
}
if ( c == 0xD1 || c == 0xF1 )
{
return ( c == 0xD1 && !changeToLowerCase ) ? 'N' : 'n';
}
if ( c == 0xAE )
{
return 'r';
}
if ( c == 0xDF )
{
return 's';
}
if ( c == 0x8E || c == 0x9E )
{
return ( c == 0x8E && !changeToLowerCase ) ? 'Z' : 'z';
}
if ( c == 0x9F || c == 0xDD || c == 0xFD || c == 0xFF )
{
return ( ( c == 0x9F || c == 0xDD ) && !changeToLowerCase ) ? 'Y' : 'y';
}
return c;
}
Related
Reading CSV file lines with hex content and convert it to decimal
Here is my CSV file and its contents are in hex. a3 42 fe 9e 89 a3 43 14 9d cd a3 43 1e 02 82 a3 43 23 bd 85 a3 43 39 d5 83 a3 43 3e b9 8d a3 43 3f 44 c0 a3 43 50 c9 49 a3 43 67 29 c8 a3 43 67 43 0d I need only the second-last value and the code to extract that value is this. void getvalues(){ std::ifstream data("mydata1.CSV"); int row_count =0; std::string line; while(std::getline(data,line)) { row_count +=1; std::stringstream lineStream(line); std::string cell; int column_count = 0; while(std::getline(lineStream,cell,' ')) { column_count+=1; if ( column_count == 5){ std::cout << std::dec<< cell[0]<< std::endl; } } } Since I am reading the lines into a string cell, I am unable to do any conversion. At first I tried wrapping the cell with an int but it returns me the ASCII value of the character which is quite obvious and I shouldn't have done that.
If you want to convert a string to an integer, you can use std::stoi, which is included in the string package. By default, you can use stoi as such: int num = std::stoi(cell) However since we want to parse a base 16 hex number, then we need to use it like: int num = std::stoi(cell, 0, 16) Quick article about this: https://www.includehelp.com/stl/convert-hex-string-to-integer-using-stoi-function-in-cpp-stl.aspx
Pine script conditions / conditional-statements
I have 6 conditions: c1 = ... c2 = ... Then if 4 of them are fullfilled (yielding 15 combinations), I will execute some command. How to do this? E.g.: cb1 = c1 and c2 and c3 and c4 cb2 = c1 and c2 and c3 and c5 cb3 = c1 and c2 and c3 and c6 cb4 = c1 and c2 and c4 and c5 cb5 = c1 and c2 and c4 and c6 cb6 = c1 and c2 and c5 and c6 cb7 = c1 and c3 and c4 and c5 cb8 = c1 and c3 and c4 and c6 cb9 = c1 and c3 and c5 and c6 cb10 = c1 and c4 and c5 and c6 cb11 = c2 and c3 and c4 and c5 cb12 = c2 and c3 and c4 and c6 cb13 = c2 and c3 and c5 and c6 cb14 = c2 and c4 and c5 and c6 cb15 = c3 and c4 and c5 and c6 // Set up alert alertcondition(condition=cb1 or cb2 or cb3 or cb4 or cb5 or cb6 or cb7 or cb8 or cb9 or cb10 or cb11 or cb12 or cb13 or cb14 or cb15, message="cb")
You can read this for some information. if (condition1 == true) and (condition2 == true) and (condition3 == true) and (condition4 == true) // Do something else if (condition2 == true) and (condition3 == true) and (condition4 == true) and (condition5 == true) // Do something else Please note the indentation.
Could we do the point system? example condition1 is ok X=1 condition2 is ok X=x+1 condition3 is ok X=x+3 condition4 is ok X=x+4 if x>0 do this else if x>1 do this else if x>2 do this ...
Fastest way for wrapping a value in an interval
I am curious about the ways to wrap a floating-point value x in a semi-closed interval [0; a[. For instance, I could have an arbitrary real number, say x = 354638.515, that I wish to fold into [0; 2π[ because I have a good sin approximation for that range. The fmod standard C functions show up quite high in my benchmarks, and by checking the source code of various libc implementations, I can understand why: the thing is fairly branch-ey, likely in order to handle a lot of IEEE754-specific issues: glibc: https://github.com/bminor/glibc/blob/master/sysdeps/ieee754/flt-32/e_fmodf.c Apple: https://opensource.apple.com/source/Libm/Libm-315/Source/ARM/fmod.c.auto.html musl: https://git.musl-libc.org/cgit/musl/tree/src/math/fmod.c Running with -ffast-math causes GCC to generate code that goes through the x87 FPU on x86/x86_64 which comes with its own set of problems (such as 80-bit doubles, FP state, and other fun things). I would like the implementation to vectorize at least semi-correctly, and if possible to not go through the x87 FPU but through vector registers at least as the rest of my code ends up vectorized, even if not necessarily an optimal way, by the compiler. This one looks much simpler: https://github.com/KnightOS/libc/blob/master/src/fmod.c In my case, I am only concerned about usual real values, not NaNs, not infinity. My range is also known at compile-time and sane (a common occurence being π/2), thus the checks for "special cases" such as range == 0 are unnecessary. Thus, what would be good implementations of fmod for that specific use case ?
Assuming that the range is constant and positive you can compute its reciprocal to avoid costly division. void fast_fmod(float * restrict dst, const float * restrict src, size_t n, float divisor) { float reciprocal = 1.0f / divisor; for (size_t i = 0; i < n; ++i) dst[i] = src[i] - divisor * (int)(src[i] * reciprocal); } The final code with a simple demo is: #include <stdlib.h> #include <stdio.h> #include <math.h> void fast_fmod(float * restrict dst, const float * restrict src, size_t n, float divisor) { float reciprocal = 1.0f / divisor; for (size_t i = 0; i < n; ++i) dst[i] = src[i] - divisor * (int)(src[i] * reciprocal); } int main() { float src[9] = {-4, -3, -2, -1, 0, 1, 2, 3, 4}; float dst[9]; float div = 3; fast_fmod(dst, src, 9, div); for (int i = 0; i < 9; ++i) { printf("fmod(%g, %g) = %g vs %g\n", src[i], div, dst[i], fmod(src[i], div)); } } produces an expected output: fmod(-4, 3) = -1 vs -1 fmod(-3, 3) = 0 vs -0 fmod(-2, 3) = -2 vs -2 fmod(-1, 3) = -1 vs -1 fmod(0, 3) = 0 vs 0 fmod(1, 3) = 1 vs 1 fmod(2, 3) = 2 vs 2 fmod(3, 3) = 0 vs 0 fmod(4, 3) = 1 vs 1 Compilation with GCC with command: $ gcc prog.c -o prog -O3 -march=haswell -lm -fopt-info-vec prog.c:8:4: optimized: loop vectorized using 32 byte vectors prog.c:8:4: optimized: loop vectorized using 32 byte vectors prog.c:8:30: optimized: basic block part vectorized using 32 byte vectors Thus the code was nicely vectorized. EDIT It looks that CLANG does even a better job vectorizing this code: 401170: c5 fc 10 24 8e vmovups (%rsi,%rcx,4),%ymm4 401175: c5 fc 10 6c 8e 20 vmovups 0x20(%rsi,%rcx,4),%ymm5 40117b: c5 fc 10 74 8e 40 vmovups 0x40(%rsi,%rcx,4),%ymm6 401181: c5 fc 10 7c 8e 60 vmovups 0x60(%rsi,%rcx,4),%ymm7 401187: c5 6c 59 c4 vmulps %ymm4,%ymm2,%ymm8 40118b: c5 6c 59 cd vmulps %ymm5,%ymm2,%ymm9 40118f: c5 6c 59 d6 vmulps %ymm6,%ymm2,%ymm10 401193: c5 6c 59 df vmulps %ymm7,%ymm2,%ymm11 401197: c4 41 7e 5b c0 vcvttps2dq %ymm8,%ymm8 40119c: c4 41 7e 5b c9 vcvttps2dq %ymm9,%ymm9 4011a1: c4 41 7e 5b d2 vcvttps2dq %ymm10,%ymm10 4011a6: c4 41 7e 5b db vcvttps2dq %ymm11,%ymm11 4011ab: c4 41 7c 5b c0 vcvtdq2ps %ymm8,%ymm8 4011b0: c4 41 7c 5b c9 vcvtdq2ps %ymm9,%ymm9 4011b5: c4 41 7c 5b d2 vcvtdq2ps %ymm10,%ymm10 4011ba: c4 41 7c 5b db vcvtdq2ps %ymm11,%ymm11 4011bf: c5 3c 59 c3 vmulps %ymm3,%ymm8,%ymm8 4011c3: c5 34 59 cb vmulps %ymm3,%ymm9,%ymm9 4011c7: c5 2c 59 d3 vmulps %ymm3,%ymm10,%ymm10 4011cb: c5 24 59 db vmulps %ymm3,%ymm11,%ymm11 4011cf: c4 c1 5c 5c e0 vsubps %ymm8,%ymm4,%ymm4 4011d4: c4 c1 54 5c e9 vsubps %ymm9,%ymm5,%ymm5 4011d9: c4 c1 4c 5c f2 vsubps %ymm10,%ymm6,%ymm6 4011de: c4 c1 44 5c fb vsubps %ymm11,%ymm7,%ymm7 4011e3: c5 fc 11 24 8f vmovups %ymm4,(%rdi,%rcx,4) 4011e8: c5 fc 11 6c 8f 20 vmovups %ymm5,0x20(%rdi,%rcx,4) 4011ee: c5 fc 11 74 8f 40 vmovups %ymm6,0x40(%rdi,%rcx,4) 4011f4: c5 fc 11 7c 8f 60 vmovups %ymm7,0x60(%rdi,%rcx,4) 4011fa: 48 83 c1 20 add $0x20,%rcx 4011fe: 48 39 c8 cmp %rcx,%rax 401201: 0f 85 69 ff ff ff jne 401170 <fast_fmod+0x40>
This is a fmod()-alternative without precision loss I wrote. The computation can take very long if the counter has a very high exponent and the denominator has a very low exponent, but it is still faster than the current Gnu C libary implementation: #include <stdint.h> #include <string.h> #include <fenv.h> #if defined(_MSC_VER) #include <intrin.h> #endif #if defined(__GNUC__) || defined(__clang__) #define likely(x) __builtin_expect((x), 1) #define unlikely(x) __builtin_expect((x), 0) #else #define likely(x) (x) #define unlikely(x) (x) #endif #define MAX_EXP (0x7FF) #define SIGN_BIT ((uint64_t)1 << 63) #define EXP_MASK ((uint64_t)MAX_EXP << 52) #define IMPLCIT_BIT ((uint64_t)1 << 52) #define MANT_MASK (IMPLCIT_BIT - 1) #define QNAN_BIT (IMPLCIT_BIT >> 1) inline uint64_t bin( double d ) { uint64_t u; memcpy( &u, &d, sizeof d ); return u; } inline double dbl( uint64_t u ) { double d; memcpy( &d, &u, sizeof u ); return d; } inline double NaN() { feraiseexcept( FE_INVALID ); return dbl( SIGN_BIT | EXP_MASK | QNAN_BIT ); } inline void normalize( uint64_t *mant, int *exp ) { #if defined(__GNUC__) || defined(__clang__) unsigned bits = __builtin_clz( *mant ) - 11; *mant <<= bits; #elif defined(_MSC_VER) unsigned long bits; _BitScanReverse64( &bits, *mant ); bits = (bits ^ 63) - 11; *mant <<= bits; #else unsigned bits = 0; for( ; !(*mant & IMPLCIT_BIT); *mant <<= 1, ++bits ); #endif *exp -= bits; } double myFmodC( double counter, double denominator ) { uint64_t const bCounter = bin( counter ), bDenom = bin( denominator ); uint64_t const sign = bCounter & SIGN_BIT; if( unlikely((bCounter & EXP_MASK) == EXP_MASK) ) // +/-[Inf|QNaN|SNaN] % ... = -QNaN return NaN(); if( unlikely((bDenom & EXP_MASK) == EXP_MASK) ) // +/-x % +/-[Inf|QNan|SNaN] if( likely(!(bDenom & MANT_MASK)) ) // +/-x % +/-Inf = -/+x return dbl( sign | bCounter & ~SIGN_BIT ); else // +/-x % +/-[QNaN|SNaN] = -NaN return NaN(); int counterExp = bCounter >> 52 & MAX_EXP, denomExp = bDenom >> 52 & MAX_EXP; uint64_t counterMant = (uint64_t)!!counterExp << 52 | bCounter & MANT_MASK, denomMant = (uint64_t)!!denomExp << 52 | bDenom & MANT_MASK; if( unlikely(!counterExp) ) // counter is denormal if( likely(!counterMant) ) // counter == +/-0.0 if( likely(denomMant) ) // +/-0.0 % +/-x = -/+0.0 return dbl( sign ); else // +/-0.0 % +/-0.0 = -QNaN return NaN(); else // normalize counter normalize( &counterMant, &counterExp ), ++counterExp; if( unlikely(!denomExp) ) // denominator is denormal if( likely(!denomMant) ) // +/-x % +/-0.0 = -/+QNaN return NaN(); else // normalize denominator normalize( &denomMant, &denomExp ), ++denomExp; int remExp = counterExp; uint64_t remMant = counterMant; for( ; ; ) { int below = remMant < denomMant; if( unlikely(remExp - below < denomExp) ) break; remExp -= below; remMant <<= below; if( unlikely(!(remMant -= denomMant)) ) { remExp = 0; break; } normalize( &remMant, &remExp ); }; if( unlikely(remExp <= 0) ) // denormal result remMant >>= -remExp + 1, remExp = 0; return dbl( sign | (uint64_t)remExp << 52 | remMant & MANT_MASK ); }
APDU Write block commands on mifare card
I have been trying to writing some data to my mifare classic cards. first I send these two commands which returns 90 00: Load Mifare Keys: FF 82 20 01 06 FF FF FF FF FF FF Authenticate: FF 86 00 03 05 01 00 05 60 00 now I'm write commands to sector 0 and block 3 and block 4 by this commands APDU_WRITE_data_1 : FF D 00 03 16 APDU_WRITE_data_1 : FF D 00 04 16 // writedata1 in block 3 ... // if (nres == SM_SUCCESS)// && //bAPDURes ) { nlenrcv = sizeof(btRcv); nlencmd = 0; btCmd[nlencmd++] = 0xFF; // CLA btCmd[nlencmd++] = 0xD6; // INS btCmd[nlencmd++] = 0x00; // P1, Mifare Block Number MSB btCmd[nlencmd++] = 0x03; // P2, Mifare Block Number LSB btCmd[nlencmd++] = 16; // Lc, Data Length memcpy(btCmd + nlencmd, btWrite_1, 16); nlencmd += 16; nres = m_Smart.RFTransmit(DEV_INTERNALRF, nlencmd, btCmd, (DWORD*)&nlenrcv, btRcv_1); // writedata2 in block 4 ... if (nres == SM_SUCCESS)// && //bAPDURes ) { nlenrcv = sizeof(btRcv); nlencmd = 0; btCmd[nlencmd++] = 0xFF; // CLA btCmd[nlencmd++] = 0xD6; // INS btCmd[nlencmd++] = 0x00; // P1, Mifare Block Number MSB btCmd[nlencmd++] = 0x04; // P2, Mifare Block Number LSB btCmd[nlencmd++] = 16; // Lc, Data Length memcpy(btCmd + nlencmd, btWrite_2, 16); nlencmd += 16; nres = m_Smart.RFTransmit(DEV_INTERNALRF, nlencmd, btCmd, (DWORD*)&nlenrcv, btRcv_2); But it doesn't work is it the APDU for writing wrong?
Loop interval changing unexpectedly
I am writing a loop to remove every third element from an array until there is only one element left. here is the code... int elimcnt = 1;//counts how many elements looped through int cnt = 0;//counts how many elements deleted for printing purposes for (int i = 0; v.size() > 1; i++, elimcnt++) { if (i == v.size()) {//reset i to the beginning when it hits the end i = 0; } if (elimcnt%in.M == 0 && elimcnt != 0) {//in.M is elimination index which is 3 v.erase(v.begin() + (elimcnt%v.size()) - 1); cnt++; if (cnt%in.K == 0) {//in.K is how often you will print which is after 7 deletes print_vector(v, cnt); } } } what actually happens when i run it is that it will correctly delete the first element but after that it deletes every 4th element from there on out. Here is an example input... A1 A2 A3 A4 A5 A6 A7 A8 A9 B1 B2 B3 B4 B5 B6 B7 B8 B9 C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6 D7 D8 D9 E1 E2 E3 E4 E5 What is supposed to be outputted... A1 A2 A4 A5 A7 A8 B1 B2 B4 B5 B7 B8 C1 C2 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6 D7 D8 D9 E1 E2 E3 E4 E5 This is what is actually outputted... A1 A2 A4 A5 A6 A8 A9 B1 B3 B4 B5 B7 B8 B9 C2 C3 C4 C6 C7 C8 D1 D2 D3 D4 D5 D6 D7 D8 D9 E1 E2 E3 E4 E5 I cant seem to figure out what is causing the code to do this so any help will be greatly appreciated.
The problem is in the expression used in the statement v.erase(v.begin() + (elimcnt%v.size()) - 1); ^^^^^^^^^^^^^^^^^^^^^ Consider a sequence of numbers 1, 2, 3, 4, 5, 6 For the first traversing of the sequence You need to delete 3 and 6 After deleting 3 you will get 1, 2, 4, 5, 6 and the variable elimcnt after the deleting will be incremented and will be equal to 4. However the size of the sequence is now equal to 5. So when elimcnt will be equal to 6 then the expression elimcnt%v.size()) - 1 will be equal to 0 and the element 1 will be deleted. I could suggest a more safe approach using iterators. for example size_t elimcnt = 0;//counts how many elements looped through size_t cnt = 0; for (auto it = v.begin(); v.size() > 1; it == v.end() ? it = v.begin() : it ) { if (++elimcnt % in.M == 0) { it = v.erase(it); if (++cnt % in.K == 0) { print_vector(v, cnt); } } else { ++it; } }