001/* 002 * Units of Measurement Implementation for Java SE 003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM. 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-363 nor the names of its 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 tec.uom.se.function; 031 032import java.io.Serializable; 033import java.math.BigDecimal; 034import java.math.MathContext; 035import java.util.Objects; 036 037import tec.uom.lib.common.function.ValueSupplier; 038import tec.uom.se.AbstractConverter; 039 040/** 041 * <p> 042 * This class represents a logarithmic converter of limited precision. Such converter is typically used to create logarithmic unit. For example:[code] 043 * Unit<Dimensionless> BEL = Unit.ONE.transform(new LogConverter(10).inverse()); [/code] 044 * </p> 045 * 046 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 047 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 048 * @version 1.0, October 10, 2016 049 */ 050public final class LogConverter extends AbstractConverter implements ValueSupplier<String> { // implements Immutable<String> { 051 052 /** 053 * 054 */ 055 private static final long serialVersionUID = -7584688290961460870L; 056 057 /** 058 * Holds the logarithmic base. 059 */ 060 private final double base; 061 /** 062 * Holds the natural logarithm of the base. 063 */ 064 private final double logOfBase; 065 066 /** 067 * Returns a logarithmic converter having the specified base. 068 * 069 * @param base 070 * the logarithmic base (e.g. <code>Math.E</code> for the Natural Logarithm). 071 */ 072 public LogConverter(double base) { 073 this.base = base; 074 this.logOfBase = Math.log(base); 075 } 076 077 /** 078 * Returns the logarithmic base of this converter. 079 * 080 * @return the logarithmic base (e.g. <code>Math.E</code> for the Natural Logarithm). 081 */ 082 public double getBase() { 083 return base; 084 } 085 086 @Override 087 public AbstractConverter inverse() { 088 return new ExpConverter(base); 089 } 090 091 @Override 092 public final String toString() { 093 if (base == Math.E) { 094 return "ln"; 095 } else { 096 return "Log(" + base + ")"; 097 } 098 } 099 100 @Override 101 public boolean equals(Object obj) { 102 if (this == obj) { 103 return true; 104 } 105 if (obj instanceof LogConverter) { 106 LogConverter that = (LogConverter) obj; 107 return Objects.equals(base, that.base); 108 } 109 return false; 110 } 111 112 @Override 113 public int hashCode() { 114 return Objects.hash(base); 115 } 116 117 @Override 118 public double convert(double amount) { 119 return Math.log(amount) / logOfBase; 120 } 121 122 @Override 123 public BigDecimal convert(BigDecimal value, MathContext ctx) throws ArithmeticException { 124 return BigDecimal.valueOf(convert(value.doubleValue())); // Reverts to 125 // double 126 // conversion. 127 } 128 129 @Override 130 public boolean isLinear() { 131 return false; 132 } 133 134 @Override 135 public String getValue() { 136 return toString(); 137 } 138}