Re: Why does we still need StrictMath?
Le 08/05/2022 à 14:15, Victor Williams Stafusa da Silva a écrit : Was that using Java 17+, which included JEP 306 delivered? No, but my understanding is that JEP 306 does not apply to Math versus StrictMath behavior. In my understanding, the strictfp keyword was only about the use of extended exponent value set in Pentium 80 bits floating point values. It impacts the behavior of arithmetic operations + - * /, but my (maybe wrong) understanding is that it does not impact which processor instruction is used for implementing Math.sin, cos, etc. Martin
Re: Why does we still need StrictMath?
Le 08/05/2022 à 10:56, Andrew Haley a écrit : Some targets (x86, in particular) have intrinsics (log, trig) that are faster than StrictMath and also more accurate. StrictMath is not about accuracy, but cross-architecture down-to-the-last bit reproducibility. Whether we still need that reproducibility is, I suppose, something for debate. In production code, maybe not. But in test code (e.g. using JUnit), when the program does a lot of trigonometric operations (e.g. map projections), I have meet cases where a test was successful on a machine but failed on another machine. The systematic use of StrictMath in all JUnit test code ensure that the difference in behavior is not in the test code, so we can focus our debugging effort on the main code. Martin
Re: Discussion about Java Floating Point?
Hello A.Z. As Raffaello said, Java arithmetic does not have any more problem than C/C++ when using IEEE 754. The "proof" of contrary is only an illusion due to the rounding behavior of C/C++ output routines, as demonstrated by Raffaello's code. Maybe some C/C++ code use Intel extended precision arithmetic (80 bits instead of 64 bits), but it only pushes the problem further, it still not an exact representation of decimal numbers. Exact representation of 0.1 using base 2 is mathematically impossible, no matter the language (it is a periodic number in base 2). Regards, Martin
Re: Questions about enhancement and Correction to Java OpenJDK Floating Point?
Hello A.Z As far as I know, the difference in output that you observed between Java and C/C++ is not caused by a difference in floating-point computation, but in a difference in the way numbers are rounded by the "printf" command. Java has a policy of showing all significant digits, while C "printf" has a policy of rounding before printing. In my opinion, this is more dangerous because it hides what really happen in floating-point computation. The following statement is not entirely true when using finite floating point precision: (…snip…) It is a mathematical fact that, for consistent, necessary and even fast term, 10% of 10% must always precisely be 1%, and by no means anything else. Above statement can be true only when using base 10 or some other bases. We could also said "It is a mathematical fact that 1/3 of 1/3 must always precisely be 1/9 and nothing else", but it can not be represented fully accurately with base 10. It can be represented fully accurately with base 3 however. There will always be examples that work in one base and not in another, and natural laws has no preference for base 10. I understand that base 10 is special for financial applications, but for many other applications (scientific, engineering, rendering…) base 2 is as good as any other base. I would even argue that base 10 can be dangerous because it gives a false sense of accuracy: it gives the illusion that rounding errors do not happen when testing with a few sample values in base 10 (like 10% of 10%), while in reality rounding errors continue to exist in the general case. Martin
Re: RFR: 8261880: Change nested classes in java.base to static nested classes where possible [v2]
On Wed, 17 Feb 2021 16:38:03 GMT, Сергей Цыпанов wrote: >> Non-static classes hold a link to their parent classes, which in many cases >> can be avoided. > > Сергей Цыпанов has updated the pull request incrementally with one additional > commit since the last revision: > > 8261880: Remove static from declarations of Holder nested classes Just for information there is similar issues in `javax.imageio.metadata.IIOMetadataFormatImpl` class in the `java.desktop` module. - PR: https://git.openjdk.java.net/jdk/pull/2589
Re: RFR: 8180352: Add Stream.toList() method
Le 06/11/2020 à 19:00, Alan Snyder a écrit : (…snip…) But a question that deserves ongoing review is whether Java should support immutable collections using a separate type hierarchy (…snip…). Maybe an alternative way (admittedly more difficult) to have immutable collections without introducing new interfaces could be to take inspiration from the C++ "const" keyword? Especially since in Java, "const" is already a reserved keyword, just not used yet. I realize that it would be a difficult task: how to handle private fields that are just caches in a const object; where to add the "const" keyword in existing JDK API; how to make such change in a backward compatible way (e.g. when a legacy code overrides a "const" method). I do not have any expectation. But given the inconvenient of alternatives, I wonder if there is some research about the long-term feasibility of a "const" semantic in Java? If it was the case, then maybe it would be better to not add immutable collection interfaces in Java for now. Regards Martin
Re: RFR: 8180352: Add Stream.toList() method
Hello Le 03/11/2020 à 21:30, fo...@univ-mlv.fr a écrit : You know that you can not change the implementation of Collectors.toList(), and you also know that if there is a method Stream.toList(), people will replace the calls to .collect(Collectors.toList()) by a call to Stream.toList() for the very same reason (…snip…) Would they would be so numerous to do this change without verifying if the specifications match? (on my side I do read the method javadoc). But even if we worry about developers not reading javadoc, the argument could go both ways: they could assume that all Stream methods accepts null and not read that Stream.toList() specifies otherwise. Martin
Re: Feature suggestion: Add static equals methods to Float and Double
Le 08/01/2019 à 19:55, Hans Boehm a écrit : > The IEEE standard does say that for quiet NaNs, the value (or one of them) > "should" be preserved by most operations on the quiet NaN. I have not heard > of implementations violating this for anything other than the "quiet" bit. > Thus I don't immediately see why it would be problematic to encode an > explicitly programmer-introduced error cause in the remaining bits (as > opposed to relying on hardware-generated patterns). I have not seen > non-testing code that does so, but I would be mildly surprised if it > doesn't exist somewhere. I confirm that such code exist and are used in production for 15 years at least in the GeoTools and Apache Spatial Information System (SIS) projects. Earth Observation data are often images mixing measurement values with different kind of missing values. So above-cited projects perform computation on float primitive types where, for example: * Real values are Sea Surface Temperatures values in °C. * One NaN bit pattern stands for values missing because the sea was hidden by a cloud. * Another NaN bit pattern stands for values missing because the pixel is over a land. * Another NaN bit pattern stands for values missing because the remote sensor did not fly over that area. * etc. Actually those data are typically encoded as integers in some file format where each missing value is associated to a different color (clouds in white, lands in brown, etc.). But they are converted to float values for performing calculations (e.g. applying the "gradient magnitude" operator provided by Java Advanced Imaging library), then converted back to integers for displaying purpose with java.awt.image.RenderedImage. It allows the use of mathematical formulas without special checks for missing values, and still preserve the lands, clouds, etc. masks in the resulting image. I have never seen yet a lost of information encoded in quiet NaN values (e.g. I have not seen a "NaN for land" mutated to a "NaN for cloud"), except if an arithmetic operation is applied on two different NaN bit patterns. Martin
Re: Thought on multiplicity of properties in Java
Hello Rémi Le 18/09/2018 à 00:28, fo...@univ-mlv.fr a écrit : > - theoretically, the covariance is defined in term of sub-typing, > trying to widen it's definition may have unintended consequences that > need studying. > Agree that it would require studying. But we have a general guidance, which is that a subtype must obey to all constraints declared in the parent type. The Java type covariance follow that rule: we can use a more specific return type in a subclass, but not the converse since it would broke the constraint defined by the return type in the parent class. The proposed "multiplicity covariance" follows the same rule: a subclass would be allowed to define a more specific multiplicity, but the converse is not allowed. For example a [0…1] multiplicity defined in the parent class can be restricted to the [1…1] multiplicity in a subclass, but can not be changed to [0…2] or any other value outside the [0…1] range. > - technically, we can implement whatever conversions we want because > the "convariance conversion" is implemented using brige, but we may > not implement that the "covariance conversion" using bridges in the > future if by example we do some kind of reification of the type > arguments, so this may hamper the possible futures of Java. > The proposed "multiplicity covariance conversion" would be implemented using bridges too. However I admit that I lack knowledge on the consequences in a context of reification. > - the conversion from Optional to a List is not a conversion already > defined by the JLS, this need also to be specified because there is no > reason to limit this conversion to only the covariance case, by > example if you have an Optional named opt, this statement > List list = opt; should compile. This means that you have to > formally defines the conversion and perhaps the reverse conversion > too, Optional opt2 = (Optional)list; at that point you > are not backward compatible with the current JLS because this code > currently always throws a CCE. > In the "multiplicity covariance" proposal, the set of conversions that are allowed is determined by the above-cited rule that multiplicity in return value can only be restricted - not widened. By labelling Foo = [1…1], Optional = [0…1] and Collection = [0…∞], we can build the set of allowed conversions. Those conversions would not be performed by casts, but by bridge methods (in widening direction because the bridge methods implement the methods defined by parent class): * [0…1] ← [1…1]: Optional.of(value); * [0…∞] ← [1…1]: List.of(value); * [0…∞] ← [0…1]: if empty Collections.emptyList() otherwise List.of(value); Martin
Re: Thought on multiplicity of properties in Java
Hello Rémi Thanks for your reply. Le 17/09/2018 à 00:54, Remi Forax a écrit : > The Java spec limit covariance to subtyping relationship only (there > is no covariance between primitive types, or between a primitive type > and it's corresponding wrapper), so you can not use Java to implement > overriding of UML properties with different multiplicity. But if you > generate the bytecode instead of generating Java code to generate the > interfaces, you are not limited by the Java spec, so you can generate > the bridge methods you want. > Yes I know. My question was if "multiplicity covariance" was something that may be worth considering at the Java language level for some future version of the specification. This is not a request to do so, only an idea. Regards, Martin
Thought on multiplicity of properties in Java
I’m deriving Java interfaces from the UML of ISO 19111 international standard, and a though come to my mind. This is not a request for changing anything in the Java language now, I’m just wondering if this is something worth to be considered for the future. This proposal would require javac to handle Optional and maybe Collection method return types in a special way, but would not require JVM change in my understanding. Sometime a property is optional in a parent class, but become mandatory in some subclasses. In UML, the [0…1] multiplicity in parent class become restricted to [1…1] multiplicity in subclasses. I wonder if javac could do a special case for catching this model as below. Allow to override: class Parent { Optional getFoo(); } with: class Child extends Parent { @MaybeSomeAnnotationMakingIntentClear @Override Foo getFoo(); } Those two methods differ only by the return type, which I think is allowed at the JVM level. In the Child class, javac would generate the following synthetic method: @Override final Optional getFoo() { return Optional.of(getFoo()); // Invoke the getFoo() method that return Foo. } Subclasses of Child can override only the method returning Foo, not Optional. In UML parlance, the [0…1] multiplicity can be restricted to [1…1] but the converse is not allowed (this is the same reasoning than method return type covariance in Java, applied to multiplicity instead than type). Invocation of getFoo() on Parent class would invoke the methods returning Optional, while invocation of getFoo() on Child class would invoke the method returning Foo. Whether the following should be a compiler error or not is an open question: Child a = ...; Optional foo = a.getFoo(); Something similar could be done for method returning Collection too, if we consider those methods as properties having a [0…∞] multiplicity which can be restricted to [0…1] or [1…1] multiplicity in subclasses. In summary, Java already has type covariance and I wonder if it could be extended to "multiplicity covariance" with javac handling Collection as [0…∞], Optional as [0…1] and Foo as [1…1]. I'm of course not asking for any action; just curious if it is worth to put on a list of possible future Java evolutions. Regards, Martin
Re: Java Float and Double changes, BigDecimal maths class, BigDecimal operators?
Le 06/03/2018 à 05:48, A Z a écrit : > Citation about problems with Java floating point: > https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf This paper is about complex numbers, operation overloading, handling of NaN, /etc./ I don't think that they are making an argument for decimal arithmetic. > People absolutely need decimal accuracy, and not floating point > approximations > Float and double are accurate in base 2, which is as good as base 10 for scientific and engineering applications (nature does not have a preferred base - our use of base 10 is only because human have 10 fingers). Base 10 is useful in some cases like financial applications, but those ones already have their own representation (e.g. integer count of 1/1000 of cents). When numbers are measurements, values like 0.1 are approximation anyway, no matter if using base 2 or base 10. IEEE754 float and double types have hardward acceleration in modern CPU. Consequently IEEE754 is used not only in Java, but also in other languages like C/C++. The C language may give an impression of accuracy because printf can round the last digits, but the actual accuracy is still the same than Java. Martin
Re: JEP 238: Multi-Version JAR Files
Le 27/02/15 16:47, Florian Weimer a écrit : > Maybe I misunderstood the multi-version JAR files proposal, but I > thought that the assumption there is that there are actual *source* > files which use newer features of the platform. > > I really don't think this tooling support will provide sufficient > enticement to developers to maintain separate 7/8/9 source branches of > their libraries. Some projects do, while admittedly maybe only a minority. For example Apache Spatial Information System (SIS) has JDK6, JDK7 and JDK8 branches. Development is done on JDK8, then ported down to JDK6, which is the target JDK platform for current releases [1]. Martin [1] http://sis.apache.org/branches.html
Re: ConcurrentModificationException in java.util.ServiceLoader (not a multi-thread issue)
Hello Peter Le 24/02/15 13:49, Peter Levart a écrit : > You could synchronize on the entire loop and just copy over the > service objects to another collection (say ArrayList). Right, but I would like to keep the laziness instantiation behaviour. > If you really must combine laziness of constructing service objects > with concurrent iterations, you can wrap the ServiceLoader.iterator() > with the following: > > public class BufferedConcurrentIterable implements Iterable { > (...snip...) Many thanks for your help. This is indeed what I did yesterday :-). But given that the current ServiceLoader behaviour results in random ConcurrentModificationException in some multi-threads environments, this can mislead the users who believe that they have a synchronization error in their own code before they realize that the issue is in ServiceLoader itself. Martin
Re: ConcurrentModificationException in java.util.ServiceLoader (not a multi-thread issue)
Le 24/02/15 09:09, Alan Bateman a écrit : > Right, it has never supported multiple iterators but as it's an > Iterable then it should unless specified otherwise. So I think this is > a bug (although one could argue that the usage is unusual, almost a > mis-use). One use case is that in a multi-thread environment, this bug implies that it is not sufficient to synchronize all direct and indirect (through Iterator) usages of ServiceLoader. We must synchronize the entire iteration loop for preventing other threads to start a new iteration before we finished the current one. This can be annoying if the work to do between two calls to Iterator.hasNext() / next() is long. Sometime it is not possible to synchronize the entire loop if we do not control the iteration (i.e. if we advance in the iterator only when the user invokes some method). The later case can be a problem even in mono-thread application. > Not clear whether it's worth doing anything about it now, this is > because ServiceLoader is going to change very significantly soon when > it is re-specified to work with modules. I'll create a bug anyway to > track it anyway. Thanks. The fact that ServiceLoader was going to be modified for Jigsaw is precisely the reason why I was wondering if it was worth to investigate more now. Martin
ConcurrentModificationException in java.util.ServiceLoader (not a multi-thread issue)
Hello all java.util.ServiceLoader does not seem to support usage of a second Iterator in the middle of a previous iteration. The attached Java file provides two simple tests with a ServiceLoader iterating over two elements. The first test creates two iterators and invokes their hasNext() / next() methods in the following order: * Iterator 1 * Iterator 2 * Iterator 1 * Iterator 2 - unexpected end of iteration here. The second test creates two iterators and invoke the hasNext() methods on both iterators before to invoke their next() methods. This result is the following exception (tested on 1.8.0_31-b13): Exception in thread "main" java.util.ConcurrentModificationException at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:711) at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:744) at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:742) at java.util.ServiceLoader$1.next(ServiceLoader.java:479) at test.ServiceLoaderTest.test2(ServiceLoaderTest.java:47) at test.ServiceLoaderTest.main(ServiceLoaderTest.java:12) (note: to run the test, the attached test.ServiceLoaderTest file needs to be in the META-INF/services/ directory). I found a Stackoverflow thread mentioning this issue 4 years ago [1], but apparently without solution. Should I look for a patch, or is the current behaviour considered okay (in which case I would suggest to warn the users in the Javadoc)? Martin [1] http://stackoverflow.com/questions/2593777/serviceloader-double-iterator-issues test.ServiceLoaderTest$I1 test.ServiceLoaderTest$I2
Re: Re: Time to retire System.runFinalizersOnExit?
Le 29/01/15 04:43, Mandy Chung a écrit : > Throwing UOE is intentional so that applications depending on existing > behavior will be modified not to use this deprecated method. Making > it a no-op makes it harder to diagnose for applications depending on > the finalizers to be invoked on exit to free resources. I opt to > throw UOE (or remove the method that will leave it for another > discussion some other day). Maybe one or two years ago, I saw a similar discussion about "almost removing" a method from the JDK. Some proposed to define a new annotation in addition to @Deprecated, something like @Retired, which would cause the javac and javadoc compilers to behave as if the method has been removed while the method would still be available at runtime for a transition period. Would it be something worth to consider? (or alternatively an optional argument to @Deprecated?) Martin
Re: JDK 9 RFR of 4477961: java.lang.Math.toDegrees(double) could be optimized
Hi Brian Le 23/09/14 00:34, Brian Burkhalter a écrit : > I created an alternate webrev using compile-time constants per your > suggestion: > > http://cr.openjdk.java.net/~bpb/4477961/webrev.01/ On a very minor formatting detail, the change in StrictMath has a misplaced empty line (before the RADIANS_TO_DEGREES constant, while it should be after). Also, would it be worth to remove the "private" modifier in StrictMath.DEGREES_TO_RADIANS and StrictMath.RADIANS_TO_DEGREES, and have Math.toDegrees and Math.toRadians to use the StrictMath constants instead than duplicating them? It would reduce slightly the size of the Math.class file by avoiding 2 field declarations. Martin
Re: Replace concat String to append in StringBuilder parameters
I had a random look at the Webrev for TreeModelEvent.java and saw the following new code: sb.append(Integer.toString(childIndices[counter])) Wouldn't the following be slightly more efficient? sb.append(childIndices[counter]) since Integer.toString(int) creates a temporary char[] array later copied in the StringBuilder, while StringBuilder.append(int) writes directly in the buffer internal array. Martin Le 21/08/14 14:53, Wang Weijun a écrit : > I filed a bug at > >https://bugs.openjdk.java.net/browse/JDK-8038277 > > Webrev in 3 parts at > >http://cr.openjdk.java.net/~weijun/8038277/client/webrev.00 >http://cr.openjdk.java.net/~weijun/8038277/core/webrev.00/ >http://cr.openjdk.java.net/~weijun/8038277/extra/webrev.00/ > > --Max
Re: 8020860: cluster Hashtable/Vector field updates for better transactional memory behaviour
Hello all Le 15/04/14 18:14, Mike Duigou a écrit : > I have updated the webrev with what I hope is the final form: > > http://cr.openjdk.java.net/~mduigou/JDK-8020860/1/webrev/ The first changes in the javadoc contains "{@code #keys keys}" and "{@code #elements elements}". I presume that you mean {@link} instead of {@code}? Martin
Re: Time to put a stop to Thread.stop?
Le 15/05/13 10:05, David Holmes a écrit : There is a huge difference between blowing away a complete process with kill and having a single thread starting to propagate an async exception, unwinding its stack and executing finally blocks with completely broken state invariants. Given the risk, what about a mechanism similar to the one which currently hides the Sun internal packages from the compilation phase but not yet from the runtime phase? Would it be acceptable to have 'javac' and 'javadoc' woking as if the 'Thread.stop(Throwable)' method did not existed anymore, while having the method still working (for now) at runtime for existing libraries? Maybe with an annotation yet stronger than @Deprecated. Martin
Unnecessary array copy in AbstractStringBuilder.indexOf(String)?
Hello all I noticed that AbstractStringBuilder.indexOf(String, int) is implemented as below: public int indexOf(String str, int fromIndex) { return String.indexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } The call to str.toCharArray() creates a copy of the String.value char[] array. This copy doesn't seem necessary since the above String.indexOf(...) method doesn't modify the array content. Shouldn't AbstractStringBuilder passes directly the reference to the String internal array instead, maybe using package-privated access to the array? Admittedly the cloned array is usually small, but the call to indexOf(String, int) is often done in a loop. Martin
Re: String.subSequence and CR#6924259: Remove offset and count fields from java.lang.String
Le 26/06/12 20:10, Mike Duigou a écrit : StringBuilder.append(string.substring(lower, upper)); by: StringBuilder.append(string, lower, upper); This would seem to be a good refactoring regardless of the substring implementation as it avoids creation of a temporary object. The rational was that the performance advantage of using System.arraycopy(...) instead than a loop over CharSequence.charAt(int) may compensate the cost of creating a temporary object. I would not be surprised if the former was faster than the later for large substrings despite the temporary object creation. However it may not be true anymore now that substring(...) performs a copy. Of course this would need to be verified with benchmark... Martin
Re: String.subSequence and CR#6924259: Remove offset and count fields from java.lang.String
If String.substring(int, int) now performs a copy of the underlying char[] array and if there is no String.subSequence(int, int) providing the old functionality, maybe the following implications should be investigated? StringBuilder.append(...) Since, in order to avoid a useless array copy, the users may be advised to replace the following pattern: StringBuilder.append(string.substring(lower, upper)); by: StringBuilder.append(string, lower, upper); would it be worth to add a special-case in the AbstractStringBuilder.append(CharSequence, int, int) implementation for the String case in order to reach the efficiency of the AbstractStringBuilder.append(String) method? The later copies the data with a single call to System.arraycopy, as opposed to the former which invoke CharSequence.charAt(int) in a loop. Integer.parseInt(...) There was a thread one years ago about allowing Integer.parseInt(String) to accept a CharSequence. http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-April/thread.html#9801 One invoked reason was performance, since the cost of calling CharSequence.toString() has been measured with the NetBeans profiler as significant (assuming that the CharSequence is not already a String) when reading large ASCII files. Now if the new String.substring(...) implementation copies the internal array, we may expect a performance cost similar to StringBuilder.toString(). Would it be worth to revisit the Integer.parseInt(String) case - and similar methods in other wrapper classes - for allowing CharSequence input? Martin Le 23/06/12 00:15, Mike Duigou a écrit : I've made a test implementation of subSequence() utilizing an inner class with offset and count fields to try to understand all the parts that would be impacted. My observations thus far: - The specification of the subSequence() method is currently too specific. It says that the result is a subString(). This would no longer be true. Hopefully nobody assumed that this meant they could cast the result to String. I know, why would you if you can just call subString() instead? I've learned to assume that somebody somewhere does always does the most unexpected thing. - The CharSequences returned by subSequence would follow only the general CharSequence rules for equals()/hashCode(). Any current usages of the result of subSequence for equals() or hashing, even though it's not advised, would break. We could add equals() and hashCode() implementations to the CharSequence returned but they would probably be expensive. - In general I wonder if parsers will be satisfied with a CharSequence that only implements identity equals(). - I also worry about applications that currently do use subSequence currently and which will fail when the result is not a String instance as String.equals() will return false for all CharSequences that aren't Strings. ie. CharSequence token =ine.subSequence(line, start, end); if (keyword.equals(token)) ... This would now fail. At this point I wonder if this is a feature worth pursuing. Mike
Re: Integer.parseInt
Le 12/04/12 10:57, Benedict Elliott Smith a écrit : I think in this case it is reasonable to leave it to the user to ensure that the input remains consistent for the duration of the call. It can be documented if necessary, but as I say I think all imperative methods come with that caveat by definition. Calling the toString() method as a solution is really no better than asking the user to do the same, albeit a little neater; the only reason a CharSequence method would be preferred is that you can avoid unnecessary object allocation. For a very lightweight method like parseInt, this can dramatically reduce the impact of making the call. We faced this issue in our project when parsing OpenStreetMap data (an open source alternative to Google Map). The amount of integers to parse is so large that the calls to the 'toString()' method has been identified as a significant bottleneck by the NetBeans profiler. We tried a copy of the 'parseInt' method with the String argument replaced by CharSequence, and noticed a significant performance gain. Martin
Strange or obsolete @see tags in some exception javadoc
Hello all Some widely-used exceptions which were defined in the old Java 1.0 days have strange or obsolete javadoc "@see" tags: http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html IllegalArgumentException declares "@see Thread#setPriority(int)". Why is Thread.setPriority(int) so special in regard to IllegalArgumentException? http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html NumberFormatException declares "@see Integer#toString()". Shouldn't it be "@see Integer#parseInt(String)" instead? http://docs.oracle.com/javase/7/docs/api/java/util/NoSuchElementException.html NoSuchElementException declares the legacy "@see Enumeration#nextElement()", but does not declare the "@see Iterator#next()" replacement. Martin
Re: StrictMath performance improvement not ported to Math?
Hello Joe Le 22/11/11 04:20, Joe Darcy a écrit : 3) In if statements, replaced: (a == 0.0d) && (Double.doubleToLongBits(a) == negativeZeroDoubleBits) by (Double.doubleToLongBits(a) == negativeZeroDoubleBits) since the later implies the former. The performance properties of the two versions of the code may differ depending on the frequency of zeros in the input and the cost of the bitwise conversion operation. I'd prefer to leave the code logic as-is in absence of some benchmarking that showed a helpful difference. I presumed that Double.doubleToRawLongBits(a) - I forgot the "Raw" in my previous post - was very cheap after HotSpot intrinsics (which exist according vmSymbols.hpp). If my old memory from 80286 assembler still have some value, it would have simply be a matter of comparing the value from the same memory address using a different machine instruction. But obviously this is only supposition, today picture is very different and I have no benchmark for confirming or refuting my supposition… I'd prefer to see a webrev with: * All min/max logic from StrictMath moved into math, including for the integral types int and long * All StrictMath min/max methods delegating to their Math counterpart Done. I updated the webrev at the same URL: http://webrev.geomatys.com/Math/min_max/index.html The new Math code is a verbatim copy-and-paste from StrictMath, including the formatting. I also made StrictMath.abs methods delegating to their Math counterpart, after making sure that the code was really identical. After this change, the only remaining duplicated code is toDegrees and toRadians. For those two methods, I added a comment saying why StrictMath dos not delegate to Math for them (because the StrictMath methods have the "strictfp" modifier - but this modifier is easy to miss, so a comment may be a worthy safety). * Verification all java/lang/Math and java/lang/StrictMath regression tests still pass I quicky tried, but it seems to be a bit tricky for me since I'm on a MacOS machine. Maybe it will be easier when the MacOS port project will be completed... Martin
StrictMath performance improvement not ported to Math?
Hello all On December 1, 2010, "darcy" committed a slight performance improvement to the StrictMath.min/max methods with floating point arguments (commit 8aabca72877c). The calls to the doubleToLongBits(double) method were replaced by calls to the doubleToRawLongBits(double) method, and similarly for the float type. Since the call to doubleToLongBits was used only in order to determine if an argument was negative zero, and since NaN can not map to the bits pattern of -0.0, the extra cost of collapsing all NaN values to a single canonical NaN (which is the only difference between doubleToLongBits and doubleToRawLongBits) was unnecessary. However this improvement has not been ported from StrictMath to Math; the more widely-used Math class still invokes the (presumed) slower doubleToLongBits(double) method. Actually it appears that most Math / StrictMath method implementations delegate to the other class: some Math methods delegates to StrictMath (mostly the methods backed by native code), and some StrictMath methods delegate to Math (mostly the methods implemented in pure-Java). The min/max methods are an exception; their implementation is copied in both classes. Maybe this explain why the code was updated in only one class and not the other? In the patch submitted below, I propose the following changes: 1) Ported the doubleToLongBits --> doubleToRawLongBits changes from StrictMath to Math. 2) Replaced StrictMath implementations by calls to Math, in order to reduce the risk that the code of only one class is updated in the future. 3) In if statements, replaced: (a == 0.0d) && (Double.doubleToLongBits(a) == negativeZeroDoubleBits) by (Double.doubleToLongBits(a) == negativeZeroDoubleBits) since the later implies the former. 4) Moved the check for (a != a) from the method beginning to the last statement, which is tested only if (a <= b) were false rather than tested unconditionally in every cases. I'm not sure if it make a real performance difference however. Webrev link: http://webrev.geomatys.com/Math/min_max/index.html Regards, Martin
Re: Miscellaneous minor patches: javadoc typos, javac warnings, etc.
Le 10/11/11 16:24, Joe Darcy a écrit : The Float and Double changes look fine. I don't know why the constructors were coded up that way; Maybe because the Float(String) / Double(String) constructors were coded in Java 1.0, while the parseFloat(String) / parseDouble(String) methods were added (at least in public API) only in Java 1.2 and someone forgot to revisit the constructors at that time... Martin
Re: Miscellaneous minor patches: javadoc typos, javac warnings, etc.
Hello Phil Le 09/11/11 18:37, Phil Race a écrit : Please do register on 2d-dev and propose the 2D changes there. Registration done, I will post in a few minutes. The hashcode change definitely needs discussion, I think there may be views on the NaN comparison as my understanding is that this is supposed to always be not equal. The proposed change is consistent with the java.lang.Double.equals(Object) behavior. It seems to me the only way to be compliant with the reflexivity contract documented in Object.equals javadoc, apart doing a "if (other == this) return true" check. Maybe whatever full compliance with Object.equals is strongly desired or not can be a question for the core group? I would like to note that incomplete compliance may be a risk when AffineTransform (or any other object) is used as keys in Hashtable: in current implementation, if an AffineTransform object with at least one NaN value is added in a Hashtable, it is impossible to remove it by a call to Hashtable.remove(Object) (we can still remove it by Iterator.remove()). (Note: my example uses Hashtable instead of HashMap because HashMap has a clever implementation that check for object references before to invoke Object.equals, which invalidate my argument. However not all implementations are that safe). PS this is such an unrelated set of changes, I am not sure it should be under one CR, even for 2D. Actually this is 8 distinct change sets, but webrev merged all my change sets in a single one. Since it is the first time I'm using webrev, I'm probably not using it in the right way. But I still have the 8 distinct changes set on my local Mercurial clone, so I can probably recreate new webrev pages if I learn how to use webrev better... Regards, Martin
java.awt.geom.AffineTransform.hashCode() is inconsistent with equals(Object)
Hello all I realize that this is a Java2D bug, but given that it is a simple equals(Object)/hashCode() implementation issue maybe this list is still relevant... AffineTransform.hashCode() method is inconsistent with equals(Object) when some 'double' values are 0.0 values of opposite sign. The reason is that 'hashCode()' uses 'doubleToLongBits(double)' which return different values for positive and negative zero, while 'equals(Object)' uses '==' which treat -0.0 as equals to +0.0. I verified in latest JDK 7 source code that this bug is still present. Trivial test case: import java.awt.geom.AffineTransform; public class AffineBug { public static void main(String[] args) { AffineTransform tr1 = new AffineTransform(); AffineTransform tr2 = new AffineTransform(); tr2.translate(-0.0, 0); System.out.println("hashCode 1: " + tr1.hashCode()); System.out.println("hashCode 2: " + tr2.hashCode()); System.out.println("equals: " + tr1.equals(tr2)); } } Current AffineTransform.equals(Object) implementation is: public boolean equals(Object obj) { if (!(obj instanceof AffineTransform)) { return false; } AffineTransform a = (AffineTransform)obj; return ((m00 == a.m00) && (m01 == a.m01) && (m02 == a.m02) && (m10 == a.m10) && (m11 == a.m11) && (m12 == a.m12)); } Possible fix would be (assuming appropriate static import): public boolean equals(Object obj) { if (!(obj instanceof AffineTransform)) { return false; } AffineTransform a = (AffineTransform)obj; return ((doubleToLongBits(m00) == doubleToLongBits(a.m00)) && (doubleToLongBits(m01) == doubleToLongBits(a.m01)) && (doubleToLongBits(m02) == doubleToLongBits(a.m02)) && (doubleToLongBits(m10) == doubleToLongBits(a.m10)) && (doubleToLongBits(m11) == doubleToLongBits(a.m11)) && (doubleToLongBits(m12) == doubleToLongBits(a.m12))); } Note that this have the side effect of considering NaN values as equal. Similar bug affect also Point2D and Rectangle2D (I did not checked the other geometric classes). Regards, Martin
java.util.Objects.requireNonNull: an opportunity for NullArgumentException?
Hello all I apologize if this question was already debated previously. I just wonder: since JDK 7 defines an Object.requireNonNull(…) method for explicit checks of argument value, does the Project-Coin expert group has considered the addition of an explicit NullArgumentException extends NullPointerException for making clear that this exception is the result of an argument check rather than some bug hidden in the middle of a code? Some kind of NullArgumentException seems a common addition in many libraries built on top of JDK. To name just a few from a quick Google search: http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/NullArgumentException.html http://www.croftsoft.com/library/code/javadoc/core/com/croftsoft/core/lang/NullArgumentException.html http://api.dpml.net/dpml/1.1.0/net/dpml/transit/NullArgumentException.html http://www.geotoolkit.org/apidocs/org/geotoolkit/util/NullArgumentException.html A blog: http://closingbraces.net/2007/02/26/nullargumentexception/ Regards, Martin