Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCUMConverterFormatter serializes seconds * 10^-5 weird #191

Open
addict3d opened this issue Jun 9, 2021 · 0 comments
Open

UCUMConverterFormatter serializes seconds * 10^-5 weird #191

addict3d opened this issue Jun 9, 2021 · 0 comments

Comments

@addict3d
Copy link

addict3d commented Jun 9, 2021

I defined seconds * 10^-5 and it serializes weird.

I expected perhaps "s/100000" or "s.10^-5". The UCUMFormat'ers all produce "s.0".

Formatter output string
UCUM Case Insensitive "s.0"
UCUM Case Sensitive "s.0"
UCUM Print "s.0"
EBNFUnitFormat "s·10^-5"

Here is a test to recreate the potential issue.

package systems.uom.ucum.format;

import org.junit.jupiter.api.Test;
import tech.units.indriya.function.MultiplyConverter;

import javax.measure.Unit;
import javax.measure.format.UnitFormat;
import javax.measure.quantity.Time;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static systems.uom.ucum.UCUM.SECOND;
import static systems.uom.ucum.format.UCUMFormat.Variant.CASE_SENSITIVE;

public class UnitFormatWithNegativeExponentFactor {
    protected static final UnitFormat FORMAT_CS = UCUMFormat.getInstance(CASE_SENSITIVE);

    /**
     * s * 10^5 => pass
     */
    @Test
    public void testExponentFactor10e5() {
        MultiplyConverter e5 = MultiplyConverter.ofExponent(10, 5);
        Unit<Time> se5 = SECOND.transform(e5);
        assertEquals("s.100000", FORMAT_CS.format(se5));
    }

    /**
     * s * (1 / 10^5) => pass
     */
    @Test
    public void testRationalFactor10e5Reciprocal() {
        MultiplyConverter e5ReciprocalRational = MultiplyConverter.ofRational(1, 100000);

        Unit<Time> s_e5 = SECOND.transform(e5ReciprocalRational);
        assertEquals("s/100000", FORMAT_CS.format(s_e5));
    }

    /**
     * s * 10^-5 => fail
     * <p>
     * Expected :s/100000
     * Actual   :s.0
     */
    @Test
    public void testExponentFactor10e5Reciprocal() {
        MultiplyConverter e5ReciprocalPow10 = MultiplyConverter.ofExponent(10, -5);
        Unit<Time> se5 = SECOND.transform(e5ReciprocalPow10);
        assertEquals("s/100000", FORMAT_CS.format(se5));
    }
}

I'm not overly familiar with this ecosystem, but it strikes me that tech.units.indriya.AbstractUnit.prefix() always results in a PowerOfIntConverter via MultiplyConverter.ofPrefix() (same as MultiplyConverter.ofExponent()). Which by luck is how I constructed the unit I was using.

Should MultiplyConverter.ofPrefix() sometimes result in a RationalConverter instead? Or should additional logic be included in UCUMConverterFormatter.formatConverter()? It seems it already handles this scenario for RationalConverter.

If we can find a good path to resolve this, I'm happy to draft a PR. Cheers!

@addict3d addict3d changed the title UCUMConverterFormatter unexpected serialization for transformed unit with negative exponent UCUMConverterFormatter serializes seconds * 10^-5 weird Jun 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants