math und debug: Mathematische Hilfsfunktionen und Diagnose
Verwenden Sie mathematische Funktionen mit Bereichsprüfung und Diagnoseausgabe.
Wave Foundation
Ganzzahlige Funktion zur Überprüfung des Bereichs
std::math::int
min_i32(a: i32, b: i32) -> i32
max_i32(a: i32, b: i32) -> i32
abs_i32_checked(x: i32) -> MathResult<i32>
clamp_i32_checked(x: i32, lo: i32, hi: i32) -> MathResult<i32>
div_floor_i32_checked(a: i32, b: i32) -> MathResult<i32>
div_ceil_i32_checked(a: i32, b: i32) -> MathResult<i32>
MathResult<T> enthält value und error. Importieren Sie die Fehlerkonstanten aus std::math::result und verwenden Sie value erst nach der Prüfung error == MATH_ERROR_NONE. Der Betrag der kleinsten vorzeichenbehafteten Ganzzahl lässt sich nicht im selben Typ darstellen; die geprüfte Betragsfunktion meldet deshalb einen Fehler. clamp weist lo > hi zurück. Die Division prüft auf einen Divisor von null und auf Bereichsüberschreitung. floor und ceil runden anders als die Ganzzahldivision, die in Richtung null abschneidet.
Gleitkommawerte klassifizieren
is_nan_f64, is_infinite_f64 und is_finite_f64 in std::math::float unterscheiden besondere Werte. Die Funktion f32 ist ebenfalls vorhanden. float_to_bits_f64(value: f64) -> u64 ist eine Funktion zum Erhalten von Speicherbits und unterscheidet sich von der numerischen Konvertierung von value as u64. NaN ist nicht einmal sich selbst gleich, daher wird es nicht gegen value == nan geprüft.
Diagnose
debug_assert(condition: bool, message: str) in std::debug::core wird beendet, nachdem ein falscher Zustand diagnostiziert wurde. Situationen, die normalerweise fehlschlagen, wie z. B. Benutzereingaben, werden mit dem Ergebniswert behandelt, und assert wird bei der Überprüfung interner Programmbedingungen verwendet, die erfüllt sein müssen.
Speichern Sie das Programm unten als main.wave und führen Sie es aus.
import("std::math::int")::{
min_i32, max_i32
};
import("std::debug::core")::{
debug_assert
};
fun main() {
var low: i32 = min_i32(9, 4);
var high: i32 = max_i32(9, 4);
debug_assert(low <= high, "invalid range");
println("{} {}", low, high);
}
Ausführungsergebnis:
4 9
Rundungsrichtung für negative Division
Vergleichen Sie, wie man -7 durch 3 dividiert. / wird in Richtung 0 gekürzt, um zu -2 zu werden. floor wählt die kleinere Ganzzahl -3 und ceil wählt die größere Ganzzahl -2 aus.
import("std::math::int")::{
div_floor_i32_checked,
div_ceil_i32_checked,
abs_i32_checked
};
import("std::math::result")::{
MathResult,
MATH_ERROR_NONE,
MATH_ERROR_OVERFLOW
};
fun main() -> i32 {
var floor: MathResult<i32> = div_floor_i32_checked(-7, 3);
var ceil: MathResult<i32> = div_ceil_i32_checked(-7, 3);
if (floor.error != MATH_ERROR_NONE || ceil.error != MATH_ERROR_NONE) {
return 1;
}
println("truncate={} floor={} ceil={}", -7 / 3, floor.value, ceil.value);
var absolute: MathResult<i32> = abs_i32_checked(-2147483648);
if (absolute.error == MATH_ERROR_OVERFLOW) {
println("absolute value is outside i32");
}
return 0;
}
Ausführungsergebnis:
truncate=-2 floor=-3 ceil=-2
absolute value is outside i32
Wenn Sie nur den Ergebniswert überprüfen, können Sie nicht zwischen dem im Fehlerfall einbezogenen Ersatzwert und dem tatsächlichen Berechnungsergebnis unterscheiden. Befolgen Sie zunächst die Reihenfolge der Überprüfung error. floor ist nützlich, wenn negative Koordinaten in ein Intervall einer bestimmten Größe eingegeben werden, und ceil ist nützlich, wenn die erforderliche Anzahl von Bündeln aufgerundet wird.
Mit welchen Fehlern sollte ich umgehen?
| Situation | Fehler | Verarbeitungsbeispiel |
|---|---|---|
| Durch Null dividieren | MATH_ERROR_DIVIDE_BY_ZERO |
Nimmt erneut die Nennereingabe vor |
| Ergebnis kann nicht im Typ gespeichert werden | MATH_ERROR_OVERFLOW |
Berechnen Sie mit breiterem Typ oder verwerfen Sie die Eingabe |
| Das Minimum ist größer als das Maximum in clamp | MATH_ERROR_INVALID_ARGUMENT |
Einstellbereich ändern |
assert ist kein Fehlerreparaturtool. Fehler bei Benutzereingaben werden durch bedingte Anweisungen und Rückgabewerte behandelt und nach Abschluss der Berechnung werden die internen Bedingungen, die erfüllt sein müssen, mit debug_assert überprüft.