1 /*
2 * Oceanus: Java Utilities
3 * Copyright 2012-2026. Tony Washer
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 * use this file except in compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17 package io.github.tonywasher.joceanus.oceanus.decimal;
18
19 import java.math.BigDecimal;
20 import java.math.RoundingMode;
21
22 /**
23 * Represents a Ratio object.
24 */
25 public class OceanusRatio
26 extends OceanusDecimal {
27 /**
28 * Standard number of decimals for Ratio.
29 */
30 protected static final int NUM_DECIMALS = 6;
31
32 /**
33 * Ratio of one.
34 */
35 public static final OceanusRatio ONE = getWholeUnits(1);
36
37 /**
38 * Number of days in a standard year.
39 */
40 private static final int DAYS_IN_YEAR = 365;
41
42 /**
43 * Constructor.
44 */
45 protected OceanusRatio() {
46 }
47
48 /**
49 * Construct a new Ratio by copying another ratio.
50 *
51 * @param pRatio the Ratio to copy
52 */
53 public OceanusRatio(final OceanusDecimal pRatio) {
54 super(pRatio.unscaledValue(), pRatio.scale());
55 adjustToScale(NUM_DECIMALS);
56 }
57
58 /**
59 * Construct a new Units by setting the value explicitly.
60 *
61 * @param pValue the unscaled value
62 * @return the new Rate
63 */
64 public static OceanusRatio getWholeUnits(final long pValue) {
65 final OceanusRatio myRatio = new OceanusRatio();
66 myRatio.setValue(adjustDecimals(pValue, NUM_DECIMALS), NUM_DECIMALS);
67 return myRatio;
68 }
69
70 /**
71 * Construct a new Ratio by the ratio between two decimals.
72 *
73 * @param pFirst the first decimal
74 * @param pSecond the second decimal
75 */
76 public OceanusRatio(final OceanusDecimal pFirst,
77 final OceanusDecimal pSecond) {
78 recordScale(NUM_DECIMALS);
79 calculateQuotient(pFirst, pSecond);
80 }
81
82 /**
83 * Create the ratio from a byte array.
84 *
85 * @param pBuffer the buffer
86 */
87 public OceanusRatio(final byte[] pBuffer) {
88 super(pBuffer);
89 }
90
91 /**
92 * Obtain inverse ratio of this ratio (i.e. 1/this rate).
93 *
94 * @return the inverse ratio
95 */
96 public OceanusRatio getInverseRatio() {
97 return new OceanusRatio(ONE, this);
98 }
99
100 /**
101 * Multiply by ratio.
102 *
103 * @param pRatio the multiplying ratio
104 * @return the new ratio
105 */
106 public OceanusRatio multiplyBy(final OceanusRatio pRatio) {
107 final OceanusRatio myRatio = new OceanusRatio();
108 myRatio.recordScale(NUM_DECIMALS);
109 myRatio.calculateProduct(this, pRatio);
110 return myRatio;
111 }
112
113 /**
114 * Obtain annualised ratio.
115 *
116 * @param pDays the number of days in the period
117 * @return the annualised ratio
118 */
119 public OceanusRatio annualise(final long pDays) {
120 /* Calculate the annualised value and convert to rate */
121 double myValue = Math.pow(doubleValue(), ((double) DAYS_IN_YEAR) / pDays);
122 myValue -= 1;
123 BigDecimal myDecimal = BigDecimal.valueOf(myValue);
124 myDecimal = myDecimal.setScale(NUM_DECIMALS, RoundingMode.HALF_UP);
125 return new OceanusRatio(new OceanusDecimal(myDecimal));
126 }
127
128 @Override
129 public void addValue(final OceanusDecimal pValue) {
130 throw new UnsupportedOperationException();
131 }
132
133 @Override
134 public void subtractValue(final OceanusDecimal pValue) {
135 throw new UnsupportedOperationException();
136 }
137 }