- Available C++ Libraries FAQ - 1 Update
- pow(0, 0) - 12 Updates
- Hateful abusive posts by Leigh Johnston, round #2 - 1 Update
- pow(0, 0) - 1 Update
- "Trip report: Fall ISO C++ standards meeting (San Diego),,2018-11-13 by Herb Sutter" - 3 Updates
- HOW can I use custom placement new with array? - 2 Updates
- Using #define in the construction of an array - 1 Update
Nikki Locke <nikki@trumphurst.com>: Nov 14 11:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
bitrex <user@example.net>: Nov 14 11:01AM -0500 > Citation, please? The only relevant text I could find has already been > quoted by Stephen Ram, and says that the value is implementation- > defined. <https://en.cppreference.com/w/cpp/numeric/math/pow> "pow(base, ±0) returns 1 for any base, even when base is NaN" "If base is zero and exp is zero, a domain error may occur." I assume this to mean that a domain error may or may not occur depending on implementation, but the operation should still return 1 regardless. Or that that particular reference is simply "wrong" as well. It also shows that "pow(+1, NAN) = 1" what the hell does 1 to the power of NaN even mean, mathematically speaking. But nobody appears to be wigging out over that one. |
bitrex <user@example.net>: Nov 14 11:06AM -0500 > computer math can't be perfectly in accord with the math of real > numbers, and often isn't. I don't know how they chose that rule; one > possibility is that it simplifies implementation of pow(). There's a bit of an abuse of terminology when we call things like std::pow or pow "functions." In analysis x^n is a _function_. Exponentiation is an _operator_. The value of the _function_ is undefined at 0^0. The behavior of an _operator_ may be defined as you like. |
bitrex <user@example.net>: Nov 14 11:14AM -0500 On 11/14/2018 11:06 AM, bitrex wrote: > Exponentiation is an _operator_. > The value of the _function_ is undefined at 0^0. The behavior of an > _operator_ may be defined as you like. That is to say the reason why the function x^n at (0, 0) is undefined in real analysis is because that's what makes the most sense for real analysis for the exponentiation operator to return, for the reasons already given. Of course it returns undefined in that situation "you" set it up that way! Or else one believes in the One True Mathematics handed down by God in which case I cannot argue anymore. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Nov 14 04:29PM >> I can't really think of many mathematical contexts where it makes much >> sense to define 0^0 as being something other than 1. > In mathematics, 0^0 is undefined. Period. No ifs, buts or maybes. Them's fight'n words! There is a very clear exception when considering integer powers. 0^0 must be 1 in those cases or almost every bit of code you write to do combinatorics or symbolic mathematics involving integer powers (polynomials, series and so one) would have to have special cases. In fact, you'd fix the special case just once by defining your own integer power function that gave 0^0 == 1 and you'd use that instead of the broken built-in one. This has nothing to do with C++ since C++ has only C's pow function and its own complex ones. C++ has no integer exponentiation operator or function to worry about, but I am sure that even you would make int ipow(int x, int y); return 1 for ipow(0, 0), wouldn't you? <snip> -- Ben. |
bitrex <user@example.net>: Nov 14 12:06PM -0500 On 11/14/2018 11:29 AM, Ben Bacarisse wrote: > int ipow(int x, int y); > return 1 for ipow(0, 0), wouldn't you? > <snip> z^n @ (0, 0) is not undefined in complex analysis either it is 0; z^n for n in the set of real numbers is a perfectly nice bijective mapping from the set of complex numbers to the set of complex numbers, continuous and infinitely differentiable everywhere. the return value of ::std::complex::pow is unambiguously implementation-defined however cuz ::std::complex::pow is not the analytic function z^n. |
bitrex <user@example.net>: Nov 14 12:14PM -0500 On 11/14/2018 03:56 AM, David Brown wrote: >> and all else is pathological edge-cases. > I thought God created the natural numbers, and all the rest is the work > of man? Nah, natural numbers are just the unit test for complex analysis. If the result of some operation in complex analysis isn't in agreement with the behavior of the natural numbers then the problem is in the operation not elsewhere. |
bitrex <user@example.net>: Nov 14 12:17PM -0500 On 11/14/2018 12:14 PM, bitrex wrote: > result of some operation in complex analysis isn't in agreement with the > behavior of the natural numbers then the problem is in the operation not > elsewhere. So should actually say they're the base case and the stuff in-between N and C are the pathological cases. |
jameskuyper@alumni.caltech.edu: Nov 14 10:08AM -0800 On Wednesday, November 14, 2018 at 11:06:23 AM UTC-5, bitrex wrote: > On 11/14/2018 09:28 AM, jameskuyper@alumni.caltech.edu wrote: ... > Exponentiation is an _operator_. > The value of the _function_ is undefined at 0^0. The behavior of an > _operator_ may be defined as you like. The only use of "function" in the text you quoted was from the C++ standard, where the definitions of terms provided by that standard overrule any other definitions. As a general rule, the reason why any term is defined in the standard is that it is used there with a meaning that might be at least subtly (and often not-so-subtly) different from the meaning it would otherwise have. Such discrepancies are the norm, not the exception. C++ Functions are defined in 6.7.2p1, primarily by cross-referece to 9.2.3.5, which explains how to declare them. std::pow() is unambiguously a C++ function (or more precisely, a family of overloaded functions, some of them templated). 11.5p1 defines what constitutes a C++ operator; pow isn't on the list. Still, I was curious to understand the distinction you were making. While I've formally studied math at a fairly high level, it's been a long time since I did so, so I reviewed the definitions (marked as specifically for use in mathematics) provided by wikipedia: "Formally, a function f from a set X to a set Y is defined by a set G of ordered pairs (x, y) such that x ∈ X, y ∈ Y, and every element of X is the first component of exactly one ordered pair in G." <https://en.wikipedia.org/wiki/Function_(mathematics)#Definition> "an operator is generally a mapping that acts on elements of a space to produce other elements of the same space." <https://en.wikipedia.org/wiki/Operator_(mathematics)> Each overload of std::pow() has a set X consisting of the outer product of the set of values represented by it's first parameter's type, and the set of values representable by it's second parameter's type. It maps each element of that set to one and only one element of the set Y, consisting of all representable values of it's return type. Note that this description applies to any particular implementation of the C/C++ standard library; different implementations might provide slightly different mappings, due to permissible variations in the accuracy with which they are implemented. This seems an excellent match to the definition of a function. However, X and Y are very different spaces, so it doesn't sound like a particularly good match to that definition of an operator. Possibly you're using different definitions for those terms? Nothing would be more typical of mathematics than the use of different definitions in different contexts - but by the same token, that should lead you to respect C++'s decision to provide it's own, overriding definitions for those terms. |
jameskuyper@alumni.caltech.edu: Nov 14 10:18AM -0800 On Wednesday, November 14, 2018 at 11:01:55 AM UTC-5, bitrex wrote: > On 11/14/2018 08:59 AM, jameskuyper@alumni.caltech.edu wrote: > > On Wednesday, November 14, 2018 at 4:31:02 AM UTC-5, bitrex wrote: ... > > defined. > <https://en.cppreference.com/w/cpp/numeric/math/pow> > "pow(base, ±0) returns 1 for any base, even when base is NaN" That's a requirement stated in the C standard; it's inherited by the C++ standard, but not explicitly stated by it, and it applies only to implementations which choose to pre#define __STDC_IEC_559__, and only to the C standard library functions inherited by C++. Rather annoyingly, it does not apply to the std::pow() overloads for complex types. |
bitrex <user@example.net>: Nov 14 02:28PM -0500 > definitions in different contexts - but by the same token, that should > lead you to respect C++'s decision to provide it's own, overriding > definitions for those terms. Essentially from the definition of a mathematical operation. Exponentiation is an operation, like +, -, differentiation operator "D", Laplace transform operator "L", etc. they are not functions. <https://en.wikipedia.org/wiki/Exponentiation> x^n is a function. So the question would be what is std::pow supposed to represent. The formal function x^n as it is used in real analysis, or the more general mathematical operator of exponentiation, but a constrained variant of it which operates only on the types it does simply due to practical limitations of the intrinsic language types i.e. you're not working with pen and paper Since the value of the formal function x^n is undefined at (0, 0) as any real analysis text would say, if that's what they were trying to represent why would the designers of the language standard allow any different, in any implementation? it would be wrong! It should just throw a domain exception no ifs-ands-or-buts. But since they did in fact do something different that would imply to me that wasn't what they were trying to make, rather a pragmatically-constrained exponentiation operator. and " ^ " was already taken. |
jameskuyper@alumni.caltech.edu: Nov 14 12:53PM -0800 On Wednesday, November 14, 2018 at 2:29:10 PM UTC-5, bitrex wrote: > On 11/14/2018 01:08 PM, jameskuyper@alumni.caltech.edu wrote: ... > Exponentiation is an operation, like +, -, differentiation operator "D", > Laplace transform operator "L", etc. they are not functions. > <https://en.wikipedia.org/wiki/Exponentiation> That describes Exponentiation as a mathematical operation, cross-referencing <https://en.wikipedia.org/wiki/Operation_(mathematics)>, which says "An operation ω is a function of the form ω : V → Y, where V ⊂ X1 × ... × Xk.". Do you agree with that definition? If so, operations are functions, and there's nothing wrong with using the term "function" to refer to an operation. ... > real analysis text would say, if that's what they were trying to > represent why would the designers of the language standard allow any > different, in any implementation? The answer for the C++ standard is that they were just incorporating the C standard library by reference. The answer for the C standard is that they were just following the lead of ISO/IEC 60559. I don't have a copy of that standard, and even if I did, it wouldn't necessarily explain why that decision was made. But I do know that in many cases ISO/IEC 60559 just codified existing practice, which often meant following the lead of Fortran. I'm not sure whether this is one of those cases, but if it is, you might want to ask why Fortran made that decision. As a general rule, if there's a discrepancy between the mathematical definition of a function, and the corresponding computer implementation of that function, it's generally because it was found to be acceptable in most cases, and more convenient for at least some cases. That's the best answer I can give you - I wasn't involved in any of the relevant decision making. > it would be wrong! It should just > throw a domain exception no ifs-ands-or-buts. But since they did in fact The specification was derived from C, which doesn't have exceptions to be thrown. C's floating point exceptions (which are incorporated by reference into C++ - see section 24.4) are very different from C++ exceptions - they don't interrupt the flow of execution, they merely set flags which can be tested after execution is complete. In the context of high-performance numerical calculations, it would often be unacceptable to interrupt the flow of execution with a C++ exception. > do something different that would imply to me that wasn't what they were > trying to make, rather a pragmatically-constrained exponentiation > operator. That seems extremely plausible. Pragmatism usually plays a big role in the development of standards. |
bitrex <user@example.net>: Nov 14 05:36PM -0500 >> trying to make, rather a pragmatically-constrained exponentiation >> operator. > That seems extremely plausible. Pragmatism usually plays a big role in the development of standards. I believe what I should have said is that std::pow(x, y) should probably be understood to represent the exponential operator, not the operation of exponentiation itself, and not the real-valued function x^n. Like "^" but in the development of C++ "^" was already taken for xor and they didn't give it a new thing. "+" could have been say add(1, 2), okay sure add(1, 2) will be a function call but "+" operator is not a function. In say Mathematica "^" means the exponential operator and what it does is context-dependent on what its operands are. If it had been given its own symbol in C++ it would've been over-loadable like any other operator I suppose; that would make sense as while the concept of "exponentiation" is easy to visualize with natural numbers as repeated multiplication exponent-number-of-times the exponentiation operator "^" is used in other contexts where what the operation it actually performs is is not really at all intuitive, like you can write A^B where both A and B are matrices. What does it "mean" to multiply matrix A with itself B times where B is a rank 47 matrix? I'm not sure I could tell you that from an intuitive perspective but it can definitely be defined to produce something, as a valid _operation_, all the way back to the Peano axioms I suppose. So it's my contention that because of the intrinsic limitations "pow" while seems to behave a lot like the plain ol' function x^n for floating point real numbers there's no mathematical law or reason it has to confirm to the analysis textbook behavior of x^n because that's not really what it "is." Just because std::pow can accept floating point real numbers like you're doing real analysis doesn't mean you have to use it that way, could also use it to strictly exponentiate values from the set of natural numbers to do set theory problems, in set theory it's perfectly natural to define 0^0 = 1 and 0^0 = undefined makes no sense, how come set theory should get the shaft in deference to what analysis says it should be? 'bout the best argument I can make. :) |
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Nov 14 02:35PM -0800 On 11/13/2018 1:04 PM, Rick C. Hodgin wrote: > On Tuesday, November 13, 2018 at 3:56:51 PM UTC-5, Chris M. Thomasson wrote: >> Have you ever read about the Giants, or Hybrids in the Bible? > The Nephilim. Indeed. I have a sneaking suspicion that the Nephilim happen to be hyper smart rebellious alien scientists. God told them not to mess around with the natural process on Earth. The Nephilim said, "FU%^&&^%%% YOU", and experimented away at full steam ahead... God basically had to destroy their abominations of desolation, their hybrid strange creations, with the: Flood...^^...^^^^...^^ Ascii art for little waves. ;^) |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 14 09:39PM ><https://en.wikipedia.org/wiki/Operation_(mathematics)>, which says "An ope= >ration =CF=89 is a function of the form =CF=89 : V =E2=86=92 Y, where V =E2= (Sorry for the bad quotation - There's a problem with the newsreader.) C already uses a term "operation". For example: |7.17.7 Operations on atomic types |7.21.4 Operations on files |3.19.5 |perform a trap |interrupt execution of the program such that no further |operations are performed |A volatile access to an object, modifying a file, or calling |a function that does any of those operations are all side |effects, which are changes in the state of the execution |environment. |Floating-point operations implicitly set the status flags |Much of this section is motivated by the desire to support |atomic operations with explicit and detailed visibility |constraints. .. But what is this, an operation? I am not sure there is a definition in ISO/IEC 9899! Maybe in the normative reference ISO/IEC 2382:2015? Yes: |operation |A well-defined action that, when applied to any permissible |combination of known entities, produces a new entity. This leads only to more questions: What is an action? When is it well-defined? Is something that does not produce new entities but changes existing entities not an operation? The definition I would personally prefer would be to define the term "operation" a the execution of a specific incarnation of an operator or of a function. For example, during the evaluation of »2+3*4«, there are two operations: »3*4« and »2+7«. For another example, the evaluation of »pow(2,3*4)« has »3*4« and »pow(2,7)«. Sometimes it might be helpful to allow "internal operations" of the implementation which do not directly correspond to a C operator or function, but on "internal operators" or "internal functions". E.e., the behavior of the evaluation of »2|3« in C might be explained based on internal operations on bits. With regard to mathematics: I sometimes find the term operation from universal algebra helpful: It also allows for operations with zero operands. This better corresponds to C functions like »rand()« than mathematical function, which do not allow for a function with zero parameters. |An n-ary operation on A is a function that takes n |elements of A and returns a single element of A. en.wikipedia.org/wiki/Universal_algebra |
woodbrian77@gmail.com: Nov 14 12:41PM -0800 On Tuesday, November 13, 2018 at 3:41:44 PM UTC-6, Lynn McGuire wrote: > effort – this wouldn't be possible without all of your help. So, thank > you, and apologies for not being able to acknowledge everyone by name." > Wow, that is a lot of new features. I'm wondering if there will be a new C that is based on 2011 C++ and that adds some of the things from 2014, 2017 and 2020 C++. A less frenzied language. > Lynn Brian Ebenezer Enterprises - In G-d we trust. https://github.com/Ebenezer-group/onwards |
David Brown <david.brown@hesbynett.no>: Nov 14 09:52PM +0100 > based on 2011 C++ and that adds some of the things > from 2014, 2017 and 2020 C++. A less frenzied > language. There is a C17, with draft standard available. It doesn't change much compared to C11, but incorporates a whole bunch of defect reports and has nicer (IMHO) typesetting. C2x is underway, with a few new features. It is not yet solidified, but you can find some information about proposals and likely features. Don't expect it to have too much new - C is intentionally a slow-moving language, unlike C++. |
Ian Collins <ian-news@hotmail.com>: Nov 15 10:27AM +1300 On 15/11/18 09:52, David Brown wrote: >> On Tuesday, November 13, 2018 at 3:41:44 PM UTC-6, Lynn McGuire wrote: >>> "Trip report: Fall ISO C++ standards meeting (San Diego)" by Herb Sutter >>> https://herbsutter.com/2018/11/13/trip-report-fall-iso-c-standards-meeting-san-diego/ <snip> > you can find some information about proposals and likely features. > Don't expect it to have too much new - C is intentionally a slow-moving > language, unlike C++. I liked this quote from origin link: "Signed integers are two's complement (JF Bastien) is the result of a courtroom drama in both WG21 (C++) and WG14 (C). After intense prosecutorial cross-examination, the witness finally admitted in both courts that, yes, all known modern computers are two's complement machines, and, no, we don't really care about using C++ (or C) on the ones that aren't. The C standard is likely to adopt the same change." About time! This one should hopefully be in the next C: "assume_aligned (Timur Doumler, Chandler Carruth) enables portable code to express an alignment optimization hint to the compiler." -- Ian |
"Öö Tiib" <ootiib@hot.ee>: Nov 14 08:50AM -0800 On Wednesday, 14 November 2018 16:27:02 UTC+2, Manfred wrote: > > new(&x.front()) char; > Also note the most confusing call of placement new to X* when given a > type 'char'. That was my extension. OP code did placement new 'X' not 'char'. I did it for to show that only the type of arguments inside () matters to what placement new is picked by overload resolution and that there won't be any diagnostics. > Also true. > In my experience I have (rarely) used placement new, but never had to > override it. I have seen it been overload for passing whatever other things but the pointer for example for to instrument the buffer somehow: void* operator new [](size_t n, char c) { char* p = new char[n]; std::fill(p, p+n, c); return p; } Such code always seems like deliberate obfuscation. One likely has to read [expr.new] of standard to figure out what is going on there and if and to what extent it is valid. |
Manfred <noname@add.invalid>: Nov 14 08:20PM +0100 On 11/14/2018 5:50 PM, Öö Tiib wrote: > On Wednesday, 14 November 2018 16:27:02 UTC+2, Manfred wrote: >> On 11/14/2018 2:33 PM, Öö Tiib wrote: [...] >>> std::cout << "Placement new to X* for size " << sz << "\n"; >>> return p; >>> } [...] > I did it for to show that only the type of arguments inside () matters > to what placement new is picked by overload resolution and that > there won't be any diagnostics. And, in fact the type of the arguments (X*) is used to resolve overloading of the operator, and 'char' to deduce the size arg 'sz' passed to the overloaded operator. As I said, most confusing. [...] |
David Brown <david.brown@hesbynett.no>: Nov 14 04:22PM +0100 On 14/11/18 14:46, Scott Lurndal wrote: > Really, I've never seen a useful "portable" "standard" C or C++ > real-world application. That's not to say they don't exist, but > they're very rare. There is a distinction between portable code, and portable programs. I doubt if there are many fully portable C or C++ programs. But there is a good deal of portable C and C++ code. It is not at all uncommon to have most of the C implementation files and headers written in portable code, with only a few specific parts written in an implementation-specific or non-portable manner. So you could have a header file that contained: static inline int popcount(unsigned int x) { return __builtin_popcount(x); } That would be non-standard and non-portable. The C file that used the code, #include'ing the header and calling the function "popcount", would be portable. So the program as a whole would be non-portable, but the C code that called the popcount function would be portable. |
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