- 2019 wish list - 5 Updates
- Halting Problem Final Conclusion [2021 update to my 2004 statement] - 2 Updates
- Merry CHRISTmas! - 2 Updates
- Why is trunc() so slow ? - 5 Updates
- Strange compiler warning... - 8 Updates
- Ridiculously high standards? - 2 Updates
"Öö Tiib" <ootiib@hot.ee>: Jan 03 08:36AM -0800 > > Why to reinvent a wheel? > I'm sure you already know this, but for open source libraries, users for > the most part do not want dependencies on other libraries. I myself am usually annoyed by wheels reinvented (square as rule) instead of using standard library, or whatever other library be it boost, eigen, sdl, rapidjson, ncurses and long list of others I know that work. > > Quite decent implementation is available > But not self-contained in one or two files. So what? What are you requiring from what you got for free? Do it yourself. You can extract it and make compile-time option to use your extracted version as third alternative to std::basic_string_view and boost::basic_string_view. Does anyone want your reinvented thing? Who? The resulting naive garbage is what I've learned to frown at. Anecdotal history of binary search is most clear example of what I observe from day to day: "When Jon Bentley assigned binary search as a problem in a course for professional programmers, he found that ninety percent failed to provide a correct solution after several hours of working on it, mainly because the incorrect implementations failed to run or returned a wrong answer in rare edge cases. A study published in 1988 shows that accurate code for it is only found in five out of twenty textbooks." <https://en.wikipedia.org/wiki/Binary_search_algorithm> It all is same about professional programmers of 2021, about binary search and about lot of other similarly "trivial" things they reinvent. If I see it then they fail my review with "Use std::lower_bound here!". |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 03 06:11PM On Sun, 2021-01-03, Öö Tiib wrote: ... > study published in 1988 shows that accurate code for it is only > found in five out of twenty textbooks." > <https://en.wikipedia.org/wiki/Binary_search_algorithm> That's weird. I remember the class circa 1991 when we tried to implement binary search, and I remember who came up with the right solution (not me). We all knew (or learned) it was hard and, more importantly, we knew how to prove an implementation was correct (with invariants and such). Perhaps our education was better than average, but why bother teaching binary search if you don't do it properly? /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
"Öö Tiib" <ootiib@hot.ee>: Jan 03 12:28PM -0800 On Sunday, 3 January 2021 at 20:11:56 UTC+2, Jorgen Grahn wrote: > invariants and such). > Perhaps our education was better than average, but why bother teaching > binary search if you don't do it properly? All people learn. Even the teachers learn. Study published 1988 made it lot better by 1991. But people forget and old teachers retire. IT has high salaries so only weak specialists become teachers and at 2021 you can easily find that majority of professional programmers fail miserably when attempting to implement binary search. Same with reinventing whatever other thing. Did you see "But [the freely available implementation is] not self-contained in one or two files." That talks loudly about Dunning Kruger effect of person not beaten hard to level of elementary competence needed in our industry. |
"daniel...@gmail.com" <danielaparker@gmail.com>: Jan 03 02:00PM -0800 On Sunday, January 3, 2021 at 11:36:19 AM UTC-5, Öö Tiib wrote: > instead of using standard library, or whatever other library be it > boost, eigen, sdl, rapidjson, ncurses and long list of others I know > that work. Most of the libraries you mention reinvent quite a few things themselves. rapidjson reinvents float parsing, and one of the 427 items on its issues list is a failure of exact float parsing in some cases. > yourself. You can extract it and make compile-time option to use your > extracted version as third alternative to std::basic_string_view and > boost::basic_string_view. Does anyone want your reinvented thing? Apparently. I have implementations of ns::basic_string_view, ns::optional, and ns::span, which are part of an open source project that has been described as "popular", and receives nice user feedback. These names resolve to the standard library equivalents if the appropriate C++ version is detected. > Who? Users. But why personalize this? What difference does that make? Daniel |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 03 10:24PM On Sun, 2021-01-03, Öö Tiib wrote: > high salaries so only weak specialists become teachers and at 2021 > you can easily find that majority of professional programmers fail > miserably when attempting to implement binary search. I might fail too, but at least I wouldn't deliver a broken implementation. > available implementation is] not self-contained in one or two files." > That talks loudly about Dunning Kruger effect of person not beaten > hard to level of elementary competence needed in our industry. I did, but decided to comment only on the binary search. I'm not sure I really want to read the OP's explanation of that. Nowaday I try to avoid crackpot ideas, and try to remember I'm not responsible to fight them. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
gamo <gamo@telecable.es>: Jan 03 09:17PM +0100 El 2/1/21 a las 19:12, olcott escribió: > (a) Halts > (b) Does Not Halt > (c) Pathological Self Reference to Halt Hello. You happen to have some insight in this problem. In which type do you clasify te option to halt *if* an arbitrary precision and/or repeated solution counter reach a thresold??? Thank you. Best. -- http://gamo.sdf-eu.org/ "What happens in EuroVegas it remains in EuroVegas" |
gamo <gamo@telecable.es>: Jan 03 10:42PM +0100 El 3/1/21 a las 21:17, gamo escribió: > *if* an arbitrary precision and/or repeated solution counter > reach a thresold??? > Thank you. Best. s/te/the/; s/tresold/treshold/; Sorry! -- http://gamo.sdf-eu.org/ "What happens in EuroVegas it remains in EuroVegas" |
Rosario19 <Ros@invalid.invalid>: Jan 03 06:20PM +0100 On Fri, 25 Dec 2020 10:06:28 -0500, "Rick C. Hodgin" wrote: >and received up into glory where He now sits in all power and authority, >even holding full power and authority over death, Hell, and the grave. >Thanks to Jesus: "Oh death, where is thy sting?" Marry Christmas, and Happy New Year to all |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jan 03 12:31PM -0800 On 1/3/2021 9:20 AM, Rosario19 wrote: >> even holding full power and authority over death, Hell, and the grave. >> Thanks to Jesus: "Oh death, where is thy sting?" > Marry Christmas, and Happy New Year to all Likewise! :^) |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 03 06:44PM +0100 I've just wondered why trunc() of the MSVCRT is so slow. So I've written my own trunc(): #include <iostream> #include <cmath> #include <cassert> #include <limits> #include <vector> #include <random> #include <chrono> #include <cassert> using namespace std; using namespace chrono; double ftrunc( double d ); float ftrunc( float f ); int main() { union { double dAssemble; struct { uint64_t mantissa : 52; uint64_t exponent : 11; uint64_t sign : 1; }; }; mt19937_64 rg; uniform_int_distribution<uint64_t> mantissaValues( 0, ((uint64_t)1 << 52) - 1 ); // equal of only fractional numbers, // mantissa with integral parts and fractions // and mantissa without fractions uniform_int_distribution<unsigned> exponentValues( 0x3FF - 52, 0x3FF + 2 * 52 - 1 ), signValues( 0, 1 ); vector<double> vd( 1'000 ); for( double &d : vd ) mantissa = mantissaValues( rg ), exponent = exponentValues( rg ), sign = signValues( rg ), d = dAssemble; for( double d : vd ) assert(ftrunc( d ) == trunc( d )); double volatile dummyValue; time_point<high_resolution_clock> start = high_resolution_clock::now(); size_t const turns = 1'000'000'000 / vd.size(); for( size_t i = turns; i; --i ) for( double d : vd ) dummyValue = ftrunc( d ); double ns = (double)duration_cast<nanoseconds>( high_resolution_clock::now() - start ).count(); cout << "ftrunc: " << ns / (vd.size() * turns) << endl; start = high_resolution_clock::now(); for( size_t i = turns; i; --i ) for( double d : vd ) dummyValue = trunc( d ); ns = (double)duration_cast<nanoseconds>( high_resolution_clock::now() - start ).count(); cout << "trunc: " << ns / (vd.size() * turns) << endl; } double ftrunc( double d ) { static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) not equal to sizeof(uint64_t)"); static_assert(numeric_limits<double>::is_iec559, "double must be IEEE-754"); // assume size_t is our CPU's native register-width static_assert(sizeof(size_t) == sizeof(uint64_t) || sizeof(size_t) == sizeof(uint32_t), "register-width must be 32 or 64 bit"); if constexpr( sizeof(size_t) == sizeof(uint64_t) ) // we have 64 bit registers { unsigned const MANTISSA_BITS = 52, EXP_BIAS = 0x3FF, INF_NAN_BASE = 0x7FF; uint64_t const EXP_MASK = (uint64_t)0x7FF << MANTISSA_BITS, SIGN_MASK = (uint64_t)0x800 << MANTISSA_BITS , MIN_INTEGRAL_DIGITS_EXP = (uint64_t) EXP_BIAS << MANTISSA_BITS, MIN_INTEGRAL_ONLY_EXP = (uint64_t)(EXP_BIAS + MANTISSA_BITS) << MANTISSA_BITS, INF_NAN_EXP = (uint64_t)INF_NAN_BASE << MANTISSA_BITS, NEG_MANTISSA_MASK = 0x000FFFFFFFFFFFFFu; union { double du; uint64_t dx; }; du = d; uint64_t exp = dx & EXP_MASK; if( exp >= MIN_INTEGRAL_DIGITS_EXP ) // value has integral digits if( exp < MIN_INTEGRAL_ONLY_EXP ) { // there are fraction-digits to mask out, mask them unsigned shift = (unsigned)(exp >> MANTISSA_BITS) - EXP_BIAS; dx &= ~(NEG_MANTISSA_MASK >> shift); return du; } else if( exp < INF_NAN_EXP ) // value is integral return du; else // infinite, NaN, SNaN // raise exception on SNaN if necessary return du + du; else { // below +/-1.0 // return +/-0.0 dx &= SIGN_MASK; return du; } } else if constexpr( sizeof(size_t) == sizeof(uint32_t) ) // we have 32 bit registers { unsigned const MANTISSA_BITS = 52, HI_MANTISSA_BITS = 20, EXP_BIAS = 0x3FF, INF_NAN_BASE = 0x7FF; uint32_t const EXP_MASK = (uint32_t)0x7FFu << HI_MANTISSA_BITS, SIGN_MASK = (uint32_t)0x800u << HI_MANTISSA_BITS, MIN_INTEGRAL_DIGITS_EXP = (uint32_t) EXP_BIAS << HI_MANTISSA_BITS, MAX_INTEGRAL32_EXP = (uint32_t)(EXP_BIAS + HI_MANTISSA_BITS) << HI_MANTISSA_BITS, MIN_INTEGRAL_ONLY_EXP = (uint32_t)(EXP_BIAS + MANTISSA_BITS) << HI_MANTISSA_BITS, INF_NAN_EXP = (uint32_t)INF_NAN_BASE << HI_MANTISSA_BITS, NEG_HI_MANTISSA_MASK = 0x000FFFFFu, NEG_LO_MANTISSA_MASK = 0xFFFFFFFFu; union { double du; struct { uint32_t dxLo; uint32_t dxHi; }; }; du = d; uint32_t exp = dxHi & EXP_MASK; if( exp >= MIN_INTEGRAL_DIGITS_EXP ) // value has integral digits if( exp < MIN_INTEGRAL_ONLY_EXP ) // there are fraction-digits to mask out if( exp <= MAX_INTEGRAL32_EXP ) { // the fraction digits are in the upper dword, mask them and zero the lower dword unsigned shift = (unsigned)(exp >> HI_MANTISSA_BITS) - EXP_BIAS; dxHi &= ~(NEG_HI_MANTISSA_MASK >> shift); dxLo = 0; return du; } else { // the fraction digits are in the lower dword, mask them unsigned shift = (unsigned)(exp >> HI_MANTISSA_BITS) - EXP_BIAS - HI_MANTISSA_BITS; dxLo &= ~(NEG_LO_MANTISSA_MASK >> shift); return du; } else if( exp < INF_NAN_EXP ) // value is integral return du; else // infinite, NaN, SNaN // raise exception on SNaN if necessary return du + du; else { // below +/-1.0 // return +/-0.0 dxHi &= SIGN_MASK; dxLo = 0; return du; } } } float ftrunc( float f ) { static_assert(sizeof(float) == sizeof(uint32_t), "sizeof(float) not equal to sizeof(uint32_t)"); static_assert(numeric_limits<float>::is_iec559, "float must be IEEE-754"); unsigned const MANTISSA_BITS = 23, EXP_BIAS = 0x7F, INF_NAN_BASE = 0xFF; uint32_t const EXP_MASK = (uint32_t)0xFF << MANTISSA_BITS, SIGN_MASK = (uint32_t)0x100 << MANTISSA_BITS , MIN_INTEGRAL_DIGITS_EXP = (uint32_t) EXP_BIAS << MANTISSA_BITS, MIN_INTEGRAL_ONLY_EXP = (uint32_t)(EXP_BIAS + MANTISSA_BITS) << MANTISSA_BITS, INF_NAN_EXP = (uint32_t)INF_NAN_BASE << MANTISSA_BITS, NEG_MANTISSA_MASK = 0x007FFFFFu; union { float fu; uint32_t fx; }; fu = f; uint32_t exp = fx & EXP_MASK; if( exp >= MIN_INTEGRAL_DIGITS_EXP ) // value has integral digits if( exp < MIN_INTEGRAL_ONLY_EXP ) { // there are fraction-digits to mask out, mask them unsigned shift = (unsigned)(exp >> MANTISSA_BITS) - EXP_BIAS; fx &= ~(NEG_MANTISSA_MASK >> shift); return fu; } else if( exp < INF_NAN_EXP ) // value is integral return fu; else // infinite, NaN, SNaN // raise exception on SNaN if necessary return fu + fu; else { // below +/-1.0 // return +/-0.0 fx &= SIGN_MASK; return fu; } } With 32 bit code my ftrunc is 1,9 times as fast in my benchmark. With 32 bit code it is about 4,9 times as fast in the same benchmark. So what's the magic behind MS' trunc() implementation I miss ? It couldn't be only that my ftrunc() is inlined and constants might be kept in registers; I think this wouldn't make a difference like that for the 64-bit-code. # |
Bo Persson <bo@bo-persson.se>: Jan 03 06:59PM +0100 On 2021-01-03 at 18:44, Bonita Montero wrote: > It couldn't be only that my ftrunc() is inlined and constants might > be kept in registers; I think this wouldn't make a difference like > that for the 64-bit-code. Are you statically linking to the C runtime, or are you calling a DLL-version of the function? Bo Persson |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 03 07:00PM +0100 > With 32 bit code my ftrunc is 1,9 times as fast in my benchmark. > With 32 bit code it is about 4,9 times as fast in the same benchmark. 64 |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 03 07:01PM +0100 >> that for the 64-bit-code. > Are you statically linking to the C runtime, or are you calling a > DLL-version of the function? Wouldn't make a big difference until the code doesn't become inlined. But even then, it bet it wouldn'T 4,9 times faster. |
Bonita Montero <Bonita.Montero@gmail.com>: Jan 03 07:14PM +0100 > Are you statically linking to the C runtime, or are you calling a > DLL-version of the function? I just tested it with linking it with /MT and /MD. The statically linked version is 21% slower; I would have expected the opposite if ever there's a difference. |
Juha Nieminen <nospam@thanks.invalid>: Jan 03 09:32AM > My point was that std::array is no less efficient that a plain array > when used as one. Also, like with other standard library containers, you'll get debug boundary checking with gcc (and probably clang) if you compile with the option -D_GLIBCXX_DEBUG, which you won't get for inbuilt arrays. (Ok, I didn't actually check that -D_GLIBCXX_DEBUG also affects std::array, but I would be very surprised if it didn't.) (And yes, I'm aware of -fsanitize=address which ought to detect out-of-bounds accesses of inbuilt arrays as well, but AFAIK it's not as reliable, because with standard library containers and -D_GLIBCXX_DEBUG the checks are added to the indexing code itself, checking against the size of the array.) |
"Öö Tiib" <ootiib@hot.ee>: Jan 03 07:47AM -0800 On Saturday, 2 January 2021 at 18:42:21 UTC+2, David Brown wrote: > that starts at one number, then increments or decrements until it > reaches a target - but it is extremely common. Optimisations and static > analysis that make use of such situations are therefore useful. Note that vast majority of for loops in modern code are range-based fors of C++11. So compiler already knows compile-time what that range of std::array is. It has embarrassingly no ways to break that range and so has no need to check it neither compile nor run time. |
spudisnotyourbud@grumpysods.com: Jan 03 04:23PM On 2 Jan 2021 19:00:15 GMT >"why?": as far as I'm concerned, std::array is (since 2011) the >default tool for fixed-size arrays. It's the /other/ solutions that >need a motivation. "In my opinion" is not an answer to Why. |
spudisnotyourbud@grumpysods.com: Jan 03 04:27PM On Sun, 3 Jan 2021 10:08:44 +1300 >Clearly it doesn't. That's why std::array has at(). >My point was that std::array is no less efficient that a plain array >when used as one. And also brings nothing to the table when dealing with fixed sized arrays where no bounds checking needs to be done except probably binary bloat. |
"Öö Tiib" <ootiib@hot.ee>: Jan 03 09:09AM -0800 > >when used as one. > And also brings nothing to the table when dealing with fixed sized arrays > where no bounds checking needs to be done except probably binary bloat. The raw array brings nothing to table. Nothing. Have to lose the size information or to use that uint8_t (*foo)[42] crap to pass reference to it or have to wrap it into struct to pass by value. If done so there are still no advantages, still as error-prone and ugly as it was. Only excuse of advocating its usage is that you had the pain of using it and want others to have same pain. IOW sadism of pathetic asshole. |
spuddy@isnotyourbuddy.co.uk: Jan 03 05:22PM On Sun, 3 Jan 2021 09:09:00 -0800 (PST) >> And also brings nothing to the table when dealing with fixed sized arrays >> where no bounds checking needs to be done except probably binary bloat. >The raw array brings nothing to table. Nothing. Have to Bringing something to the table implies something more than already existed. The raw array is what already existed so by definition it wouldn't. >lose the size information or to use that uint8_t (*foo)[42] crap to pass >reference to it or have to wrap it into struct to pass by value. If done so >there are still no advantages, still as error-prone and ugly as it was. A MAC is fixed size, it NEVER changes. There is no need for anything other than a C array. >it and want others to have same pain. IOW sadism of pathetic asshole. Ad homenim - the last resort of someone with no argument. Nice going. Oh, and its spelt ARSEhole unless you're speaking in the american dialect. |
"Öö Tiib" <ootiib@hot.ee>: Jan 03 09:44AM -0800 > >The raw array brings nothing to table. Nothing. Have to > Bringing something to the table implies something more than already existed. > The raw array is what already existed so by definition it wouldn't. So there are no reasons to return to it ever as it has no advantages whatsoever. > >there are still no advantages, still as error-prone and ugly as it was. > A MAC is fixed size, it NEVER changes. There is no need for anything other than > a C array. Compiler has no concept of MAC. The std::array is in every sense as good or better array than C array, also for MAC. > >it and want others to have same pain. IOW sadism of pathetic asshole. > Ad homenim - the last resort of someone with no argument. Nice going. > Oh, and its spelt ARSEhole unless you're speaking in the american dialect. You failed to show any other motivation of pushing inferior choice so I guessed correctly? 😀 OK I can call you "pathetic arsehole" if you so wish. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 03 06:13PM >>default tool for fixed-size arrays. It's the /other/ solutions that >>need a motivation. > "In my opinion" is not an answer to Why. Correct. I'll reformulate: I know there's been a long discussion about this, but to address the "why?": as far as I'm concerned, std::array is (since 2011) the default tool for fixed-size arrays. It's the /other/ solutions that need a motivation. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Brian Wood <woodbrian77@gmail.com>: Jan 02 04:09PM -0800 On Saturday, January 2, 2021 at 8:41:18 AM UTC-6, Öö Tiib wrote: > attempts of cheating). No way I would let anyone identify > themselves for reading my site or for downloading and trying > something I said is free to try there. I'm not asking anyone to identify themselves for reading my site or downloading my open-source software. If you want to use my closed-source software, you have to have an account. > his stuff so badly to make account? FlatBuffers do not require > me to make account. Probably it is some kind of scam to get > my e-mail or something and then spam me. I've been on this list for over 16 years and have been improving my software. We could, for example, go back to the first commits of my repo and compare how long it takes to build then and now, the sizes of the executables then and now, the additional functionality, etc. I believe having some closed-source software (private property) is the way to go. > Should I > manufacture some false, throw-away identity to try his > garbage? Yuck. Feel free to point out some weaknesses. My FixedVector class is new and it needs some help. I think these programs are in fairly good shape: https://github.com/Ebenezer-group/onwards/blob/master/src/tiers/genz.cc https://github.com/Ebenezer-group/onwards/blob/master/src/tiers/cmwA.cc Only been working on them for 11 years. > See, you have already lost by asking for account. Providing a SaaS was a great idea when I started and still is. Building a (walled) garden is a privilege and adventure. I hope to continue to grow into these areas: cross-platform, middleware, network-programming, serialization, messaging, managed-services. Brian Ebenezer Enterprises - Enjoying programming again. https://webEbenezer.net |
"Öö Tiib" <ootiib@hot.ee>: Jan 03 07:34AM -0800 > On Saturday, January 2, 2021 at 8:41:18 AM UTC-6, Öö Tiib wrote: Read again: > functionality, etc. > I believe having some closed-source software (private property) > is the way to go. We are not talking about you, we are talking about your potential customers who do not know you nor care about you. > > garbage? Yuck. > Feel free to point out some weaknesses. My FixedVector > class is new and it needs some help. I haven't even tried to use it. Only looked into code. Code like all the other millions of lines of code I've seen. Problem of none of programmers is that they lack code for something. There is usually annoyingly long list of choices instead. So what matters are benefits, downsides and effort needed to use one or other in that long list. You have made the item that you name "middleware writer" tiresome to even evaluate if it has any benefits whatsoever in that pile of inconveniences so it never enters that list of choices of smart and hard-working people. > https://github.com/Ebenezer-group/onwards/blob/master/src/tiers/genz.cc > https://github.com/Ebenezer-group/onwards/blob/master/src/tiers/cmwA.cc > Only been working on them for 11 years. Yes, people do not care about you or your code. I said "Throw that away, no one cares. That part only makes it hard for you to make successful things. Care about convenience and benefit of others." Only if you ever cared about others for just a bit there is chance that they start to care about whatever you have made. > to continue to grow into these areas: cross-platform, > middleware, network-programming, serialization, > messaging, managed-services. Yes, and people do not care about you, your code or your "walled garden". Think why you fought edit war of Wikipedia with Leigh? You wanted to advertise your "walled garden" so people would come to see it. Why? Why you spam about thing no one wants to see? May be few wanted to see it ever. No one of these few has said that they did like what they saw. It is because you did not care about them but about yourself. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment