jaulib v1.3.0
Jau Support Library (C++, Java, ..)
All Classes Namespaces Files Functions Variables Pages
IntMath.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24package org.jau.util;
25
26public class IntMath {
27
28 /**
29 * Returns the value of the sign function.
30 * <pre>
31 * -1 for x < 0
32 * 0 for x = 0
33 * 1 for x > 0
34 * </pre>
35 * Implementation is type safe.
36 * @param x the integral number
37 * @return function result
38 */
39 public static int sign(final int x) {
40 return (0 < x ? 1 : 0) - (x < 0 ? 1 : 0);
41 }
42
43 /**
44 * See {@link #sign(int)}.
45 */
46 public static int sign(final long x) {
47 return (0 < x ? 1 : 0) - (x < 0 ? 1 : 0);
48 }
49 /**
50 * See {@link #sign(int)}.
51 */
52 public static short sign(final short x) {
53 return (short) ( (0 < x ? 1 : 0) - (x < 0 ? 1 : 0) );
54 }
55
56 /**
57 * Safely inverts the sign of an integral number.
58 * <p>
59 * Implementation takes special care to have T_MIN, i.e. std::numeric_limits<T>::min(),
60 * converted to T_MAX, i.e. std::numeric_limits<T>::max().<br>
61 * This is necessary since <code>T_MAX < | -T_MIN |</code> and the result would
62 * not fit in the return type T otherwise.
63 * </p>
64 * Hence for the extreme minimum case:
65 * <pre>
66 * jau::invert_sign<int32_t>(INT32_MIN) = | INT32_MIN | - 1 = INT32_MAX
67 * </pre>
68 * Otherwise with x < 0:
69 * <pre>
70 * jau::invert_sign<int32_t>(x) = | x | = -x
71 * </pre>
72 * and x >= 0:
73 * <pre>
74 * jau::invert_sign<int32_t>(x) = -x
75 * </pre>
76 * @param x
77 * @return
78 */
79 public static int invert_sign(final int x) {
80 return Integer.MIN_VALUE == x ? Integer.MAX_VALUE : -x;
81 }
82
83 /**
84 * See {@link #invert_sign(int)}.
85 */
86 public static long invert_sign(final long x) {
87 return Long.MIN_VALUE == x ? Long.MAX_VALUE : -x;
88 }
89 /**
90 * See {@link #invert_sign(int)}.
91 */
92 public static short invert_sign(final short x) {
93 return Short.MIN_VALUE == x ? Short.MAX_VALUE : (short)-x;
94 }
95
96 /**
97 * Returns the absolute value of an integral number
98 * <p>
99 * Implementation uses jau::invert_sign() to have a safe absolute value conversion, if required.
100 * </p>
101 * @tparam T an integral number type
102 * @param x the integral number
103 * @return function result
104 */
105 public static int abs(final int x) {
106 return sign(x) < 0 ? invert_sign( x ) : x;
107 }
108
109 /**
110 * See {@link #abs(int)}
111 */
112 public static long abs(final long x) {
113 return sign(x) < 0 ? invert_sign( x ) : x;
114 }
115 /**
116 * See {@link #abs(int)}
117 */
118 public static short abs(final short x) {
119 return sign(x) < 0 ? invert_sign( x ) : x;
120 }
121
122 /**
123 * Returns the number of decimal digits of the given integral value number using std::log10<T>().<br>
124 * If sign_is_digit == true (default), treats a potential negative sign as a digit.
125 * <pre>
126 * x < 0: 1 + (int) ( log10( -x ) ) + ( sign_is_digit ? 1 : 0 )
127 * x = 0: 1
128 * x > 0: 1 + (int) ( log10( x ) )
129 * </pre>
130 * Implementation uses jau::invert_sign() to have a safe absolute value conversion, if required.
131 * <p>
132 * Convenience method, reusing precomputed sign of value to avoid redundant computations.
133 * </p>
134 * @param x the integral integer
135 * @param x_sign the pre-determined sign of the given value x
136 * @param sign_is_digit if true and value is negative, adds one to result for sign. Defaults to true.
137 * @return digit count
138 */
139 public static int digits10(final int x, final int x_sign, final boolean sign_is_digit) {
140 if( x_sign == 0 ) {
141 return 1;
142 }
143
144 if( x_sign < 0 ) {
145 return 1 + (int)( Math.log10( invert_sign( x ) ) ) + ( sign_is_digit ? 1 : 0 );
146 } else {
147 return 1 + (int)( Math.log10( x ) );
148 }
149 }
150
151 /**
152 * See {@link #digits10(int, int, boolean)
153 */
154 public static int digits10(final long x, final int x_sign, final boolean sign_is_digit) {
155 if( x_sign == 0 ) {
156 return 1;
157 }
158
159 if( x_sign < 0 ) {
160 return 1 + (int)( Math.log10( invert_sign( x ) ) ) + ( sign_is_digit ? 1 : 0 );
161 } else {
162 return 1 + (int)( Math.log10( x ) );
163 }
164 }
165
166 /**
167 * Returns the number of decimal digits of the given integral value number using std::log10<T>().
168 * If sign_is_digit == true (default), treats a potential negative sign as a digit.
169 * <pre>
170 * x < 0: 1 + (int) ( log10( -x ) ) + ( sign_is_digit ? 1 : 0 )
171 * x = 0: 1
172 * x > 0: 1 + (int) ( log10( x ) )
173 * </pre>
174 * Implementation uses jau::invert_sign() to have a safe absolute value conversion, if required.
175 * @tparam T an integral integer type
176 * @param x the integral integer
177 * @param sign_is_digit if true and value is negative, adds one to result for sign. Defaults to true.
178 * @return digit count
179 */
180 public static int digits10(final int x, final boolean sign_is_digit) {
181 return digits10(x, sign(x), sign_is_digit);
182 }
183
184 /**
185 * See {@link #digits10(int, boolean)
186 */
187 public static int digits10(final long x, final boolean sign_is_digit) {
188 return digits10(x, sign(x), sign_is_digit);
189 }
190
191}
static int digits10(final long x, final int x_sign, final boolean sign_is_digit)
See digits10(int, int, boolean)
Definition: IntMath.java:154
static int sign(final int x)
Returns the value of the sign function.
Definition: IntMath.java:39
static long abs(final long x)
See abs(int).
Definition: IntMath.java:112
static int invert_sign(final int x)
Safely inverts the sign of an integral number.
Definition: IntMath.java:79
static int digits10(final int x, final int x_sign, final boolean sign_is_digit)
Returns the number of decimal digits of the given integral value number using std::log10<T>().
Definition: IntMath.java:139
static short abs(final short x)
See abs(int).
Definition: IntMath.java:118
static int digits10(final long x, final boolean sign_is_digit)
See digits10(int, boolean)
Definition: IntMath.java:187
static long invert_sign(final long x)
See invert_sign(int).
Definition: IntMath.java:86
static int sign(final long x)
See sign(int).
Definition: IntMath.java:46
static int digits10(final int x, final boolean sign_is_digit)
Returns the number of decimal digits of the given integral value number using std::log10<T>().
Definition: IntMath.java:180
static int abs(final int x)
Returns the absolute value of an integral number.
Definition: IntMath.java:105
static short sign(final short x)
See sign(int).
Definition: IntMath.java:52
static short invert_sign(final short x)
See invert_sign(int).
Definition: IntMath.java:92