1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.layout;
21
22 public class MathUtils {
23
24
25
26
27 public static final double EPSILON = 0.0000001;
28
29
30
31
32
33
34
35 public static void adjustRemainders(double[] list, double bias) {
36 for (double v : list) {
37 double lastBias;
38 if (bias < 0.0) {
39 lastBias = findAndAdjustMaxRemainder(list);
40 } else {
41 lastBias = findAndAdjustMinRemainder(list);
42 }
43 if (isZero(lastBias)) {
44 break;
45 }
46 bias += lastBias;
47 }
48
49 assert isZero(bias);
50 }
51
52 public static double findAndAdjustMaxRemainder(double[] list) {
53 double max = 0.0;
54 Integer indexOfMax = null;
55 for (int i = 0; i < list.length; i++) {
56 double remainder = remainder(list[i]);
57 if (remainder > max + EPSILON) {
58 max = remainder;
59 indexOfMax = i;
60 }
61 }
62 if (indexOfMax != null) {
63 list[indexOfMax] += 1.0 - max;
64 return 1.0 - max;
65 }
66 return 0.0;
67 }
68
69 public static double findAndAdjustMinRemainder(double[] list) {
70 double min = 1.0;
71 Integer indexOfMin = null;
72 for (int i = 0; i < list.length; i++) {
73 double remainder = remainder(list[i]);
74 if (remainder == 0) {
75 continue;
76 }
77 if (remainder < min - EPSILON) {
78 min = remainder;
79 indexOfMin = i;
80 }
81 }
82 if (indexOfMin != null) {
83 list[indexOfMin] -= min;
84 return -min;
85 }
86 return 0.0;
87 }
88
89 public static double remainder(double v) {
90 return v - Math.floor(v);
91 }
92
93 public static boolean isZero(double factor) {
94 return Math.abs(factor) < EPSILON;
95 }
96
97 public static boolean isNotZero(double factor) {
98 return Math.abs(factor) >= EPSILON;
99 }
100
101 public static boolean isInteger(double value) {
102 return isZero(value - Math.round(value));
103 }
104
105 public static boolean isNotInteger(double value) {
106 return isNotZero(value - Math.round(value));
107 }
108 }