001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2020, Units of Measurement project. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, 008 * are permitted provided that the following conditions are met: 009 * 010 * 1. Redistributions of source code must retain the above copyright notice, 011 * this list of conditions and the following disclaimer. 012 * 013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions 014 * and the following disclaimer in the documentation and/or other materials provided with the distribution. 015 * 016 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products 017 * derived from this software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package tech.units.indriya.internal.function.radix; 031 032import java.util.Objects; 033 034import javax.measure.UnitConverter; 035 036import tech.units.indriya.function.Calculus; 037import tech.units.indriya.spi.NumberSystem; 038 039/** 040 * Internal utility for {@link MixedRadixSupport}. 041 * 042 * @author Andi Huber 043 * @since 2.0 044 */ 045public interface Radix { 046 047 /** 048 * Multiply without precision loss. 049 * @param number 050 * @return 051 */ 052 Number multiply(Number number); 053 054 /** 055 * Returns a two-element Number array containing {number / radix, number % radix} 056 * @param number 057 * @param roundRemainderTowardsZero - whether the division remainder should be rounded towards ZERO 058 * @return 059 */ 060 Number[] divideAndRemainder(Number number, boolean roundRemainderTowardsZero); 061 062 // -- FACTORIES 063 064 public static Radix ofNumberFactor(Number number) { 065 return new NumberFactorRadix(number); 066 } 067 068 public static Radix ofMultiplyConverter(UnitConverter linearUnitConverter) { 069 Objects.requireNonNull(linearUnitConverter, "unitConverter cannot be null"); 070 if(!linearUnitConverter.isLinear()) { 071 throw new IllegalArgumentException("unitConverter is expected to be linear"); 072 } 073 Number radix = Calculus.currentNumberSystem().narrow(linearUnitConverter.convert(1)); 074 return new NumberFactorRadix(radix); 075 } 076 077 // -- RADIX IMPLEMENTATION 078 079 //can be made private with later java versions 080 public static class NumberFactorRadix implements Radix { 081 082 private final Number radix; 083 084 public NumberFactorRadix(Number radix) { 085 this.radix = ns().narrow(radix); 086 } 087 088 @Override 089 public Number multiply(Number number) { 090 Number result = ns().multiply(radix, ns().narrow(number)); 091 return ns().narrow(result); 092 } 093 094 @Override 095 public Number[] divideAndRemainder(Number number, boolean roundRemainderTowardsZero) { 096 097 Number[] result = ns().divideAndRemainder( 098 ns().narrow(number), 099 radix, 100 roundRemainderTowardsZero); 101 result[0] = ns().narrow(result[0]); 102 result[1] = ns().narrow(result[1]); 103 return result; 104 } 105 106 private static NumberSystem ns() { 107 return Calculus.currentNumberSystem(); 108 } 109 110 } 111 112 113}