All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.jfachwert.money.internal.Zahlenwert.kt Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021 by Oliver Boehm
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * (c)reated 01.05.21 by oliver ([email protected])
 */
package de.jfachwert.money.internal

import de.jfachwert.math.Bruch
import de.jfachwert.pruefung.exception.LocalizedIllegalArgumentException
import java.math.BigDecimal
import java.math.BigInteger
import java.math.MathContext
import javax.money.NumberValue

/**
 * Diese Klasse wurde als Alternative zur DefaultNumberValue eingefuehrt.
 * Damit entfaellt die Abhaengigkeit zum 'org.javamoney.moneta.spi'-Paket
 * im moneta-bp-Modul.
 *
 * @since 4.0
 */
class Zahlenwert(val number: Number) : NumberValue() {

    /**
     * Liefert den Zahlenwert als [Byte] (evtl. gerundet).
     */
    override fun toByte(): Byte {
        return toBigDecimal().toByte()
    }

    /**
     * Liefert den Zahlenwert als [Char] (evtl. gerundet).
     */
    override fun toChar(): Char {
        return toInt().toChar()
    }

    /**
     * Liefert den Zahlenwert als [Double] (evtl. gerundet).
     */
    override fun toDouble(): Double {
        return this.number.toDouble()
    }

    /**
     * Liefert den Zahlenwert als [Float] (evtl. gerundet).
     */
    override fun toFloat(): Float {
        return toBigDecimal().toFloat()
    }

    /**
     * Liefert den Zahlenwert als [Int] (evtl. gerundet oder abgeschnitten).
     */
    override fun toInt(): Int {
        return toBigDecimal().toInt()
    }

    /**
     * Liefert den Zahlenwert als [Long] (evtl. gerundet oder abgeschnitten).
     */
    override fun toLong(): Long {
        return toBigDecimal().toLong()
    }

    /**
     * Liefert den Zahlenwert als [Short] (evtl. gerundet oder abgeschnitten).
     */
    override fun toShort(): Short {
        return toBigDecimal().toShort()
    }

    /**
     * Liefert den Zahlenwert als [BigDecimal].
     */
    fun toBigDecimal(): BigDecimal {
        when (this.number) {
            is BigDecimal -> return this.number
        }
        return BigDecimal(this.number.toString())
    }

    /**
     * Liefert den Zahlenwert als [Bruch] zurueck.
     *
     * @since 4.1
     */
    fun toBruch() : Bruch {
        return Bruch.of(toString())
    }

    override fun toString(): String {
        return toBigDecimal().toString()
    }

    /**
     * Liefert den Typ des Zahlenwerts.
     *
     * @return Typ des Zahlenwerts, nicht `null`.
     */
    override fun getNumberType(): Class<*> {
        return number.javaClass
    }

    /**
     * Liefert die *Praezision* eines `MonetaryAmount` (Anzahl Ziffern).
     *
     * @return *Praezision* eines `MonetaryAmount`.
     */
    override fun getPrecision(): Int {
        return toBigDecimal().precision()
    }

    /**
     * Liefert die *Skala* des Zahlenwerts. Bei positiven Zahlen (oder 0) ist dies
     * die Anzahl der Nachkommastellen. Bei negativen Zahlen ist dies der Exponent,
     * mit dem der Wert multipliziert wird. Dh.h eine Skala von `-3` bedeuted eine
     * Multiplikation mit 1000.
     *
     * @return Skala von `MonetaryAmount`.
     */
    override fun getScale(): Int {
        return toBigDecimal().scale()
    }

    /**
     * Liefert einen Zahlenwert als `int` so wie er ist.
     *
     * @return Zahlenwert als `int`.
     * @throws ArithmeticException falls der Zahlenwert nicht in ein `int` passt.
     */
    override fun intValueExact(): Int {
        return toBigDecimal().intValueExact()
    }

    /**
     * Liefert einen Zahlenwert als `long` so wie er ist.
     *
     * @return Zahlenwert als `long`.
     * @throws ArithmeticException falls der Zahlenwert nicht in ein `long` passt.
     */
    override fun longValueExact(): Long {
        return toBigDecimal().longValueExact()
    }

    /**
     * Liefert einen Zahlenwert als `double` so wie er ist.
     *
     * @return Zahlenwert als `double`.
     * @throws ArithmeticException falls der Zahlenwert nicht in ein `double` passt.
     */
    override fun doubleValueExact(): Double {
        return toBigDecimal().toDouble()
    }

    /**
     * Liefert den numerischen Wert als `Number`. Evtl. wird der Wert dabei
     * abgeschnitten, um in den Zieltyp zu passen.
     *
     * @param numberType Konkrete Number-Klasse, die zurueckgelieft wird.
     * Es werden folgende Number-Typen unterstuezt:
     *
     *  * `java.lang.Long`
     *  * `java.lang.Double`
     *  * `java.lang.Number`
     *  * `java.math.BigInteger`
     *  * `java.math.BigDecimal`
     *
     * @return Zahlenwert eines MonetaryAmount's.
     */
    override fun  numberValue(numberType: Class): T {
        when (numberType) {
            java.lang.Short::class.java -> return number.toShort() as T
            java.lang.Integer::class.java -> return number.toInt() as T
            java.lang.Long::class.java -> return number.toLong() as T
            java.lang.Float::class.java -> return number.toFloat() as T
            java.lang.Double::class.java -> return number.toDouble() as T
            java.lang.Byte::class.java -> return number.toByte() as T
            java.math.BigInteger::class.java -> {
                val x: BigInteger = BigDecimal(number.toString()).toBigInteger()
                return x as T
            }
        }
        return this.number as T
    }

    /**
     * Liefert den aktuellen Zahlenwert gemaess [java.math.MathContext]
     * gerundet zurueck.
     *
     * @param mathContext [java.math.MathContext] mit Rundungs-Mode
     * @return gerunderter Zahlenwert (nicht null).
     * @see java.math.BigDecimal.round
     */
    override fun round(mathContext: MathContext?): NumberValue {
        return Zahlenwert(toBigDecimal().round(mathContext))
    }

    /**
     * Access the numeric value as `Number`. Hereby no truncation will be performed to fit the
     * value into the target data type.
     *
     * @param numberType The concrete number class to be returned. Basically the following Number types,
     * must be supported if available on the corresponding runtime platform:
     *
     *  * `java.lang.Long`
     *  * `java.lang.Double`
     *  * `java.lang.Number`
     *  * `java.math.BigInteger`, currently not available on all platforms.
     *  * `java.math.BigDecimal`, currently not available on all platforms.
     *
     * @return the (possibly) truncated value of the MonetaryAmount's.
     * @throws ArithmeticException If the value must be truncated to fit the target datatype.
     */
    override fun  numberValueExact(numberType: Class): T {
        val valueExact = this.numberValue(numberType)
        if (toBigDecimal().toString().equals(valueExact.toString())) {
            return valueExact
        } else {
            throw LocalizedIllegalArgumentException(number, "data_type $numberType")
        }
    }

    /**
     * Diese Methode ermittelt den Zaehler, wenn man die aktuelle Zahl als
     * Bruch betrachtet. Dabei gilt:
     * 
`
     * w = longValue()
     * n = getFractionNominator() (Zaehler)
     * d = getFractionDenominator() (Nenner)
    `
* * * the following must be always true: * *
`
     * !(w<0 && n>0)  and
     * !(w>0 && n<0)  and
     * d>0            and
     * |n| < d        // || = absolute value
    `
* . * * @return the amount's fraction numerator.. */ override fun getAmountFractionNumerator(): Long { return toBruch().zaehler.toLong() } /** * Diese Methode ermittelt den Nenner, wenn man die aktuelle Zahl als * Bruch betrachtet. Dabei gilt: *
`
     * w = longValue()
     * n = getFractionNominator()
     * d = getFractionDenominator()
    `
* * * the following must be always true: * *
`
     * !(w<0 && n>0)  and
     * !(w>0 && n<0)  and
     * d>0            and
     * |n| < d        // || = absolute value
    `
* . * * @return the amount's fraction denominator. */ override fun getAmountFractionDenominator(): Long { return toBruch().nenner.toLong() } companion object { /** * Liefert einen Zahlenwert. */ @JvmStatic fun of(n: Number) : Zahlenwert { return Zahlenwert(n) } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy