mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
Merge pull request #424 from MartinTheDragon/factorials
UFFR wants factorials, ...
This commit is contained in:
commit
e407f33c85
@ -8,6 +8,7 @@ import org.lwjgl.input.Keyboard;
|
|||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ public class GUICalculator extends GuiScreen {
|
|||||||
|
|
||||||
int x = (width - xSize) / 2;
|
int x = (width - xSize) / 2;
|
||||||
int y = (height - ySize) / 2;
|
int y = (height - ySize) / 2;
|
||||||
inputField = new GuiTextField(fontRendererObj, x + 5, y + 5, 210, 13);
|
inputField = new GuiTextField(fontRendererObj, x + 5, y + 8, 210, 13);
|
||||||
inputField.setTextColor(-1);
|
inputField.setTextColor(-1);
|
||||||
inputField.setCanLoseFocus(false);
|
inputField.setCanLoseFocus(false);
|
||||||
inputField.setFocused(true);
|
inputField.setFocused(true);
|
||||||
@ -42,10 +43,12 @@ public class GUICalculator extends GuiScreen {
|
|||||||
if (!inputField.textboxKeyTyped(p_73869_1_, p_73869_2_))
|
if (!inputField.textboxKeyTyped(p_73869_1_, p_73869_2_))
|
||||||
super.keyTyped(p_73869_1_, p_73869_2_);
|
super.keyTyped(p_73869_1_, p_73869_2_);
|
||||||
|
|
||||||
|
String input = inputField.getText().replaceAll("[^\\d+\\-*/^!.()\\sA-Za-z]+", "");
|
||||||
|
|
||||||
if (p_73869_1_ == 13 || p_73869_1_ == 10) { // when pressing enter (CR or LF)
|
if (p_73869_1_ == 13 || p_73869_1_ == 10) { // when pressing enter (CR or LF)
|
||||||
try {
|
try {
|
||||||
double result = Double.parseDouble(latestResult);
|
double result = evaluateExpression(input);
|
||||||
String plainStringRepresentation = (new BigDecimal(result)).toPlainString();
|
String plainStringRepresentation = (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString();
|
||||||
GuiScreen.setClipboardString(plainStringRepresentation);
|
GuiScreen.setClipboardString(plainStringRepresentation);
|
||||||
inputField.setText(plainStringRepresentation);
|
inputField.setText(plainStringRepresentation);
|
||||||
inputField.setCursorPositionEnd();
|
inputField.setCursorPositionEnd();
|
||||||
@ -54,8 +57,6 @@ public class GUICalculator extends GuiScreen {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String input = inputField.getText().replaceAll("[^\\d+\\-*/^.()\\sA-Za-z]+", "");
|
|
||||||
|
|
||||||
if (input.isEmpty()) {
|
if (input.isEmpty()) {
|
||||||
latestResult = "?";
|
latestResult = "?";
|
||||||
return;
|
return;
|
||||||
@ -115,7 +116,9 @@ public class GUICalculator extends GuiScreen {
|
|||||||
while (!operators.isEmpty() && hasPrecedence(String.valueOf(tokens[i]), operators.peek()))
|
while (!operators.isEmpty() && hasPrecedence(String.valueOf(tokens[i]), operators.peek()))
|
||||||
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
||||||
operators.push(Character.toString(tokens[i]));
|
operators.push(Character.toString(tokens[i]));
|
||||||
} else if (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z') {
|
} else if (tokens[i] == '!') {
|
||||||
|
values.push((double) factorial((int) Math.round(values.pop())));
|
||||||
|
}else if (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z') {
|
||||||
StringBuilder charBuffer = new StringBuilder();
|
StringBuilder charBuffer = new StringBuilder();
|
||||||
while (i < tokens.length && (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z'))
|
while (i < tokens.length && (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z'))
|
||||||
charBuffer.append(tokens[i++]);
|
charBuffer.append(tokens[i++]);
|
||||||
@ -229,9 +232,52 @@ public class GUICalculator extends GuiScreen {
|
|||||||
double exponent = evaluateExpression(input.substring(powerOperatorIndex + 1, exponentExpressionEnd));
|
double exponent = evaluateExpression(input.substring(powerOperatorIndex + 1, exponentExpressionEnd));
|
||||||
double result = Math.pow(base, exponent);
|
double result = Math.pow(base, exponent);
|
||||||
// use big decimal to avoid scientific notation messing with the calculation
|
// use big decimal to avoid scientific notation messing with the calculation
|
||||||
input = input.substring(0, baseExpressionStart) + (new BigDecimal(result)).toPlainString() + input.substring(exponentExpressionEnd);
|
input = input.substring(0, baseExpressionStart) + (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString() + input.substring(exponentExpressionEnd);
|
||||||
} while (input.contains("^"));
|
} while (input.contains("^"));
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Maybe switch the whole calculator to using BigInteger/BigDecimal?
|
||||||
|
// SplitRecursive algorithm
|
||||||
|
private static int factorial(int in) {
|
||||||
|
if (in < 0) throw new IllegalArgumentException("Factorial needs n >= 0");
|
||||||
|
if (in < 2) return 1;
|
||||||
|
int p = 1, r = 1;
|
||||||
|
factorialCurrentN = 1;
|
||||||
|
int h = 0, shift = 0, high = 1;
|
||||||
|
int log2n = log2(in);
|
||||||
|
while (h != in) {
|
||||||
|
shift += h;
|
||||||
|
h = in >> log2n--;
|
||||||
|
int len = high;
|
||||||
|
high = (h - 1) | 1;
|
||||||
|
len = (high - len) / 2;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
p *= factorialProduct(len);
|
||||||
|
r *= p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r << shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int factorialCurrentN;
|
||||||
|
|
||||||
|
private static int factorialProduct(int in) {
|
||||||
|
int m = in / 2;
|
||||||
|
if (m == 0) return factorialCurrentN += 2;
|
||||||
|
if (in == 2) return (factorialCurrentN += 2) * (factorialCurrentN += 2);
|
||||||
|
return factorialProduct(in - m) * factorialProduct(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int log2(int in) {
|
||||||
|
int log = 0;
|
||||||
|
if((in & 0xffff0000) != 0) { in >>>= 16; log = 16; }
|
||||||
|
if(in >= 256) { in >>>= 8; log += 8; }
|
||||||
|
if(in >= 16) { in >>>= 4; log += 4; }
|
||||||
|
if(in >= 4) { in >>>= 2; log += 2; }
|
||||||
|
return log + (in >>> 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user