Wenn es teilbar ist, berechnen Sie bitte bis zu dem Punkt, an dem es teilbar ist. Wenn es jedoch nicht teilbar ist, suchen Sie immer den Quotienten mit der gleichen Anzahl gültiger Ziffern. Ich denke, es wird für eine Anwendung notwendig sein, die das Berechnungsergebnis der Division wie einen Taschenrechner anzeigt. Ich konnte im Netz keinen guten Weg finden, also habe ich selbst darüber nachgedacht (`・ ω ・ ´)
(Hinzugefügt am 16.07.2018) Ich habe unten in GIF ein Anwendungsbeispiel hinzugefügt, um zu verdeutlichen, was ich erreichen möchte. Dieses Bild wurde übrigens mit einer von mir entwickelten Taschenrechner-App namens Calc Leaf aufgenommen.
Selbst wenn die Antwort eine unendliche Zahl ist, besteht der Zweck darin, sie innerhalb des anzeigbaren Bereichs korrekt anzuzeigen.
Hier sind einige Ausgabebeispiele. Ich werde es hier weglassen, aber wenn Sie die erhaltene Antwort mit "Dezimalformat" formatieren, sieht die Anzeige gut aus.
Division.java
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Division {
public static final int SIGNIFICANT_DIGITS = 3; //Anzahl gültiger Ziffern
public static void main(String[] args) {
try {
System.out.println(divided("10000", "3")); // 3330
System.out.println(divided("1000", "3")); // 333
System.out.println(divided("100", "3")); // 33.3
System.out.println(divided("10", "3")); // 3.33
System.out.println(divided("1", "3")); // 0.333
System.out.println(divided("1", "30")); // 0.0333
System.out.println(divided("1", "300")); // 0.00333
System.out.println(divided("1", "3000")); // 0.000333
System.out.println(divided("1", "30000")); // 0.0000333
} catch(NumberFormatException nfe) {
System.out.println("Error: Not a number.");
} catch(ArithmeticException ae) {
System.out.println("Error: Impossible to calculate.");
} catch(Exception e) {
System.out.println("Error: Unexpected.");
}
}
public static String divided(String dividend, String divisor) throws Exception {
BigDecimal bdDividend = new BigDecimal(dividend);
BigDecimal bdDivisor = new BigDecimal(divisor);
BigDecimal answer = null;
try {
//Wenn es teilbar ist, teilen Sie es so wie es ist
answer = bdDividend.divide(bdDivisor);
} catch(ArithmeticException arithmeticException) {
//Wenn es nicht teilbar ist, berechnen Sie eine gültige Skala (in diesem Beispiel wird die Rundung gerundet).
answer = bdDividend.divide(bdDivisor, getSignificantScale(bdDividend, bdDivisor), RoundingMode.HALF_UP);
}
return answer.stripTrailingZeros().toPlainString();
}
public static int getSignificantScale(BigDecimal dividend, BigDecimal divisor) {
//Absolutwert ohne nachgestellte Nullen nach dem Dezimalpunkt
BigDecimal bd1 = dividend.abs().stripTrailingZeros();
BigDecimal bd2 = divisor.abs().stripTrailingZeros();
//Konvertieren Sie in natürliche Zeichenfolgen gemäß natürlichen Zahlen
int decimalDigits = bd1.scale() > bd2.scale() ? bd1.scale() : bd2.scale();
if (decimalDigits < 0) decimalDigits = 0;
String s1 = bd1.scaleByPowerOfTen(decimalDigits).toPlainString();
String s2 = bd2.scaleByPowerOfTen(decimalDigits).toPlainString();
//Berechnen Sie eine gültige Skala und geben Sie sie zurück
return SIGNIFICANT_DIGITS - (s1.length() - s2.length()) - (s1.compareTo(s2) >= 0 ? 1 : 0);
}
}
Sie können es kopieren und in Try kotlin einfügen. Sie können "let" verwenden, um "val" in einer Zeile zu erstellen, in der Sie "decimalDigits" möchten, aber ich habe es gestoppt, weil es subtil ist.
Division.kt
import java.math.BigDecimal
import java.math.RoundingMode
const val SIGNIFICANT_DIGITS: Int = 3 //Anzahl gültiger Ziffern
fun main(args: Array<String>) {
try {
println(divided("10000", "3")) // 3330
println(divided("1000", "3")) // 333
println(divided("100", "3")) // 33.3
println(divided("10", "3")) // 3.33
println(divided("1", "3")) // 0.333
println(divided("1", "30")) // 0.0333
println(divided("1", "300")) // 0.00333
println(divided("1", "3000")) // 0.000333
println(divided("1", "30000")) // 0.0000333
} catch(nfe: NumberFormatException) {
println("Error: Not a number.")
} catch(ae: ArithmeticException) {
println("Error: Impossible to calculate.")
} catch(e: Exception) {
println("Error: Unexpected.")
}
}
fun divided(dividend: String, divisor: String): String {
val bdDividend = BigDecimal(dividend)
val bdDivisor = BigDecimal(divisor)
val answer = try {
//Wenn es teilbar ist, teilen Sie es so wie es ist
bdDividend.divide(bdDivisor)
} catch(ae: ArithmeticException) {
//Wenn es nicht teilbar ist, berechnen Sie eine gültige Skala (in diesem Beispiel wird die Rundung gerundet).
bdDividend.divide(bdDivisor, getSignificantScale(bdDividend, bdDivisor), RoundingMode.HALF_UP)
}
return answer.stripTrailingZeros().toPlainString()
}
fun getSignificantScale(dividend: BigDecimal, divisor: BigDecimal): Int {
//Absolutwert ohne nachgestellte Nullen nach dem Dezimalpunkt
val bd1 = dividend.abs().stripTrailingZeros()
val bd2 = divisor.abs().stripTrailingZeros()
//Konvertieren Sie in natürliche Zeichenfolgen gemäß natürlichen Zahlen
var decimalDigits = if (bd1.scale() > bd2.scale()) bd1.scale() else bd2.scale()
if (decimalDigits < 0) decimalDigits = 0
val s1 = bd1.scaleByPowerOfTen(decimalDigits).toPlainString()
val s2 = bd2.scaleByPowerOfTen(decimalDigits).toPlainString()
//Berechnen Sie eine gültige Skala und geben Sie sie zurück
return SIGNIFICANT_DIGITS - (s1.length - s2.length) - (if (s1 >= s2) 1 else 0)
}
Sie können den obigen Code selbst testen und nach Belieben verwenden. Der von mir durchgeführte Testcode wurde auf ~~ github hochgeladen (veröffentlicht als Antwort auf Kommentare von kaizen_nagoya). Wir haben ungefähr 50 Muster basierend auf der Beziehung zwischen der zu teilenden Zahl und der zu teilenden Zahl, der Position des Dezimalpunkts, positiv / negativ und ob es sich um eine Exponentialschreibweise handelt oder nicht, überprüft und die Anforderungen geklärt. Es ist jedoch nicht zu leugnen, dass es an Objektivität mangelt, weil ich es alleine gemacht habe (´ ・ ω ・ `) Also, diejenigen, die überprüfen und erneut verifizieren, sind willkommen! Wenn Sie Informationen zu Bibliotheken oder Referenzseiten haben, die dasselbe tun, würde ich mich sehr freuen, wenn Sie mich darüber informieren könnten! (Ich habe jetzt darüber nachgedacht, aber es kann im mathematischen Wörterbuch aufgeführt sein. Ich habe es nicht.)
getSignificantScale
wird tatsächlich in meiner entwickelten Taschenrechner-App CalcLeaf verwendet, ist aber tatsächlich ein wenig Es gibt einen Unterschied in der Implementierung.
Der Punkt ist, dass "0 zurückgegeben wird, wenn das Berechnungsergebnis einer gültigen Skala negativ ist", wie unten gezeigt.
Sample.java
int significantScale = SIGNIFICANT_DIGITS - (s1.length() - s2.length()) - (s1.compareTo(s2) >= 0 ? 1 : 0);
return significantScale < 0 ? 0 : significantScale;
Im Fall eines Taschenrechners ist es beispielsweise unangenehm, wenn die Antwort von 1.000.000.000.000 ÷ 3 333.333.333.330 lautet, und Calc Leaf hat sie als Spezifikation angepasst.
Ich wünschte, ich könnte es standardmäßig mit Java API tun. Ich frage mich, ob Leute in Java darüber nachdenken werden, wenn sie es sehen.
Recommended Posts