
Numeric.pudu
Pudu40 lines1.5 KB
1/** @Utils.Numeric.Module — saturating integers and float conversion */2module PuduLangResilience.Utils.Numeric34import Std.Decimal as Decimal5import Std.Math.Float as Float6import Std.Option as Option789export const LARGEST: Int = 9223372036854775807101112export fn add(left: Int, right: Int) -> Int {13 if left > LARGEST - right { LARGEST } else { left + right }14}151617export fn multiply(left: Int, right: Int) -> Int {18 if left == 0 || right == 0 { return 0 }19 if left > LARGEST / right { LARGEST } else { left * right }20}212223export fn toFloat(value: Int) -> Float { Decimal.toFloat64(Decimal.fromInt(value)) }24252627export fn toInt(value: Float) -> Int {28 if !Float.isFinite(value) { return LARGEST }29 if value <= 0.0 { return 0 }30 if value >= 9.0e18 { return LARGEST }31 let whole = Float.floor(value)32 let parsed = Option.andThen(Decimal.parse(show(whole)), fn(exact: Decimal) -> Option[Int] { Decimal.toInt(Decimal.floor(exact)) })33 Option.unwrapOr(parsed, LARGEST)34}353637export fn partsOf(ratio: Decimal, whole: Int) -> Int {38 Option.unwrapOr(Decimal.toInt(Decimal.floor(ratio * Decimal.fromInt(whole))), 0)39}40