You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Actual physical units can have dimensions that are non-integer (most of the time square-root). This often happens with spectral densities (square root of Hertz), but also in many other domains.
This cannot be defined with the current Unit API because (1) Unit.getBaseDimensions() returns a Map<Unit, Integer>; (2) Dimsension.getBaseDimensions() returns a Map<Unit,Integer>; (3) Dimension.pow() and Unit.pow() accept only int as argument.
Dimension.getBaseDimensions() returns a Map<Unit,Integer>; (3) Dimension.pow() and Unit.pow() accept only int as argument.
This is not really a problem because either Integer.intValue() or a cast between Integer and int should both work. @SebHess Was this the only concern, or are there significant examples for e.g. floating-point dimensions?
This is not really a problem because either Integer.intValue() or a cast between Integer and int should both work. Was this the only concern, or are there significant examples for e.g. floating-point dimensions?
In my understanding, he wished that Map<Unit,Integer> would have been something like Map<Unit,Fraction> instead (Fraction does not exist in the JDK, I'm using that only for expressing the intend). The example given is spectral densities with units of s^−½.
Map<Unit,Integer> cannot be changed without compatibility break. Furthermore there is no clear alternative to Integer in the standard JDK: Fraction does not exist, and Float or Double may be too flexible. While this issue is not impossible to resolve, it is not an easy one neither.
@desruisseaux Yes, that is exactly what I had in mind. Note that there are empirical laws in physics and chemisty that are expressed as an arbitrary (real) power of a quantity, thus implying real power of units.
An example is the electron emission from a metal by electric and thermal effects: if the metal is cold, the current is given by the Fowler-Nordheim law and implies fractional powers of the field, while for warmer metal, the empirical thermo-field law applies, with real powers of the temperature and field.
Thus for completeness, Integer should be replaced by either Float or Double.
It is true that this issue breaks the existing API, but one solution could be replacing Map<Unit, Integer> by Map<Unit, ? extends Number> ? This would be OK API-wise and should not break existing implementation, although it would allow them to evolve toward non-integer powers of unit.
BigDecimal.pow() or BigInteger.pow() also just accept an int value. That being the native JDK numeric classes with the highest precision (BigDecimal should be used instead of Double or Float if you calculate with very big numbers) we modeled some of the API after that for Unit or Quantity.
Even Apache Commons Numbers has an int pow() method in Fraction or BigFraction, closest to the RationalNumber inside the Indriya RI.
Only Complex numbers in Apache Common Numbers allow a pow(double) and even a pow(Complex),
Unlike Fraction the Complex class does not extend number, so for some operations using pow(Number) may not even be sufficient.
Although we have an SPI for other number systems in the RI, there is currently just the default internal implementation, and Apache Commons Numbers or other more sophisticated number systems are not used.
Until we really deal with irrational numbers in the RI, it makes no sense to use arguments, even the JDK does not need in its biggest numeric types, which also goes along @desruisseaux' earlier comments.
Set this to deferred, we may revisit it in a future API version, if either different number systems are used by at least the RI, or the JDK goes there with new numeric types.
Thus for completeness, Integer should be replaced by either Float or Double.
Just as a side note, using Number would be much more flexible the implementation might still restrict to some types.
Regarding API compatibility, maybe adding a set of new methods and then use a custom interface like Lookup<Unit, Number> instead of Map<Unit, ...> would be more appropriate and easier to use.
Activity
keilw commentedon Nov 1, 2023
This is not really a problem because either
Integer.intValue()or a cast betweenIntegerandintshould both work.@SebHess Was this the only concern, or are there significant examples for e.g. floating-point dimensions?
desruisseaux commentedon Nov 1, 2023
In my understanding, he wished that
Map<Unit,Integer>would have been something likeMap<Unit,Fraction>instead (Fractiondoes not exist in the JDK, I'm using that only for expressing the intend). The example given is spectral densities with units of s^−½.Map<Unit,Integer>cannot be changed without compatibility break. Furthermore there is no clear alternative toIntegerin the standard JDK:Fractiondoes not exist, andFloatorDoublemay be too flexible. While this issue is not impossible to resolve, it is not an easy one neither.SebHess commentedon Nov 2, 2023
@desruisseaux Yes, that is exactly what I had in mind. Note that there are empirical laws in physics and chemisty that are expressed as an arbitrary (real) power of a quantity, thus implying real power of units.
An example is the electron emission from a metal by electric and thermal effects: if the metal is cold, the current is given by the Fowler-Nordheim law and implies fractional powers of the field, while for warmer metal, the empirical thermo-field law applies, with real powers of the temperature and field.
Thus for completeness, Integer should be replaced by either Float or Double.
It is true that this issue breaks the existing API, but one solution could be replacing
Map<Unit, Integer>byMap<Unit, ? extends Number>? This would be OK API-wise and should not break existing implementation, although it would allow them to evolve toward non-integer powers of unit.keilw commentedon Oct 12, 2024
BigDecimal.pow()orBigInteger.pow()also just accept anintvalue. That being the native JDK numeric classes with the highest precision (BigDecimalshould be used instead ofDoubleorFloatif you calculate with very big numbers) we modeled some of the API after that forUnitorQuantity.Even Apache Commons Numbers has an
int pow()method in Fraction or BigFraction, closest to theRationalNumberinside the Indriya RI.Only Complex numbers in Apache Common Numbers allow a
pow(double)and even apow(Complex),Unlike
FractiontheComplexclass does not extend number, so for some operations usingpow(Number)may not even be sufficient.Although we have an SPI for other number systems in the RI, there is currently just the default internal implementation, and Apache Commons Numbers or other more sophisticated number systems are not used.
Until we really deal with irrational numbers in the RI, it makes no sense to use arguments, even the JDK does not need in its biggest numeric types, which also goes along @desruisseaux' earlier comments.
Set this to deferred, we may revisit it in a future API version, if either different number systems are used by at least the RI, or the JDK goes there with new numeric types.
laeubi commentedon Jan 2, 2026
Just as a side note, using
Numberwould be much more flexible the implementation might still restrict to some types.Regarding API compatibility, maybe adding a set of new methods and then use a custom interface like
Lookup<Unit, Number>instead ofMap<Unit, ...>would be more appropriate and easier to use.