mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
LF: clean shifting BigNumeric builtin (#9704)
CHANGELOG_BEGIN CHANGELOG_END
This commit is contained in:
parent
7a97d88f42
commit
fc745f2224
@ -264,7 +264,7 @@ instance Pretty BuiltinExpr where
|
||||
BESubBigNumeric -> "SUB_BIGNUMERIC"
|
||||
BEMulBigNumeric -> "MUl_BIGNUMERIC"
|
||||
BEDivBigNumeric -> "DIV_BIGNUMERIC"
|
||||
BEShiftBigNumeric -> "SHIFT_BIGNUMERIC"
|
||||
BEShiftBigNumeric -> "SHIFT_RIGHT_BIGNUMERIC"
|
||||
BEToNumericBigNumeric -> "TO_NUMERIC_BIGNUMERIC"
|
||||
BEFromNumericBigNumeric -> "TO_BIGNUMERIC_NUMERIC"
|
||||
BEToTextBigNumeric -> "TO_TEXT_BIGNUMERIC"
|
||||
|
@ -494,7 +494,7 @@ decodeBuiltinFunction = pure . \case
|
||||
LF1.BuiltinFunctionSUB_BIGNUMERIC -> BESubBigNumeric
|
||||
LF1.BuiltinFunctionMUL_BIGNUMERIC -> BEMulBigNumeric
|
||||
LF1.BuiltinFunctionDIV_BIGNUMERIC -> BEDivBigNumeric
|
||||
LF1.BuiltinFunctionSHIFT_BIGNUMERIC -> BEShiftBigNumeric
|
||||
LF1.BuiltinFunctionSHIFT_RIGHT_BIGNUMERIC -> BEShiftBigNumeric
|
||||
LF1.BuiltinFunctionTO_NUMERIC_BIGNUMERIC -> BEToNumericBigNumeric
|
||||
LF1.BuiltinFunctionTO_BIGNUMERIC_NUMERIC -> BEFromNumericBigNumeric
|
||||
LF1.BuiltinFunctionTO_TEXT_BIGNUMERIC -> BEToTextBigNumeric
|
||||
|
@ -510,7 +510,7 @@ encodeBuiltinExpr = \case
|
||||
BESubBigNumeric -> builtin P.BuiltinFunctionSUB_BIGNUMERIC
|
||||
BEMulBigNumeric -> builtin P.BuiltinFunctionMUL_BIGNUMERIC
|
||||
BEDivBigNumeric -> builtin P.BuiltinFunctionDIV_BIGNUMERIC
|
||||
BEShiftBigNumeric -> builtin P.BuiltinFunctionSHIFT_BIGNUMERIC
|
||||
BEShiftBigNumeric -> builtin P.BuiltinFunctionSHIFT_RIGHT_BIGNUMERIC
|
||||
BEToNumericBigNumeric -> builtin P.BuiltinFunctionTO_NUMERIC_BIGNUMERIC
|
||||
BEFromNumericBigNumeric -> builtin P.BuiltinFunctionTO_BIGNUMERIC_NUMERIC
|
||||
BEToTextBigNumeric -> builtin P.BuiltinFunctionTO_TEXT_BIGNUMERIC
|
||||
|
@ -569,7 +569,7 @@ enum BuiltinFunction {
|
||||
SUB_BIGNUMERIC = 140; // *Available in versions >= 1.13*
|
||||
MUL_BIGNUMERIC = 141; // *Available in versions >= 1.13*
|
||||
DIV_BIGNUMERIC = 142; // *Available in versions >= 1.13*
|
||||
SHIFT_BIGNUMERIC = 143; // *Available in versions >= 1.13*
|
||||
SHIFT_RIGHT_BIGNUMERIC = 143; // *Available in versions >= 1.13*
|
||||
TO_NUMERIC_BIGNUMERIC = 144; // *Available in versions >= 1.13*
|
||||
TO_BIGNUMERIC_NUMERIC = 145; // *Available in versions >= 1.13*
|
||||
TO_TEXT_BIGNUMERIC = 146; // *Available in versions >= 1.13*
|
||||
|
@ -580,7 +580,7 @@ enum BuiltinFunction {
|
||||
SUB_BIGNUMERIC = 140; // *Available in versions >= 1.13*
|
||||
MUL_BIGNUMERIC = 141; // *Available in versions >= 1.13*
|
||||
DIV_BIGNUMERIC = 142; // *Available in versions >= 1.13*
|
||||
SHIFT_BIGNUMERIC = 143; // *Available in versions >= 1.13*
|
||||
SHIFT_RIGHT_BIGNUMERIC = 143; // *Available in versions >= 1.13*
|
||||
TO_NUMERIC_BIGNUMERIC = 144; // *Available in versions >= 1.13*
|
||||
TO_BIGNUMERIC_NUMERIC = 145; // *Available in versions >= 1.13*
|
||||
TO_TEXT_BIGNUMERIC = 146; // *Available in versions >= 1.13*
|
||||
|
@ -1838,7 +1838,7 @@ private[lf] object DecodeV1 {
|
||||
BuiltinFunctionInfo(SUB_BIGNUMERIC, BSubBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(MUL_BIGNUMERIC, BMulBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(DIV_BIGNUMERIC, BDivBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(SHIFT_BIGNUMERIC, BShiftBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(SHIFT_RIGHT_BIGNUMERIC, BShiftRightBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(TO_NUMERIC_BIGNUMERIC, BToNumericBigNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(TO_BIGNUMERIC_NUMERIC, BToBigNumericNumeric, minVersion = bigNumeric),
|
||||
BuiltinFunctionInfo(TO_TEXT_BIGNUMERIC, BToTextBigNumeric, minVersion = bigNumeric),
|
||||
|
@ -300,8 +300,8 @@ class ProtoTest extends AnyWordSpec with Matchers with TableDrivenPropertyChecks
|
||||
("file", "Linux hash", "windows hash"),
|
||||
(
|
||||
"daml_lf_1.proto",
|
||||
"66c18f32acff0c75cc2cbcb55e175749aedc246ccb9630cc959b462ddf717af4",
|
||||
"33c4f75472db481862a745d18b7e28843aa284666b79b822172cd7ead1dc6ca8",
|
||||
"6d0869fd8b326cc82f7507ec9deb37520af23ccc4c03a78af623683eb5df2bee",
|
||||
"7cc33b6549ce425608858b1cd1c5a56fd4e928bb1df015f8ad24019377eb4154",
|
||||
),
|
||||
(
|
||||
"daml_lf.proto",
|
||||
|
@ -26,8 +26,8 @@ module BuiltinMod {
|
||||
MUL_BIGNUMERIC;
|
||||
val divBigNumeric: Int64 -> RoundingMode -> BigNumeric -> BigNumeric -> BigNumeric =
|
||||
DIV_BIGNUMERIC;
|
||||
val shiftBigNumeric: Int64 -> BigNumeric -> BigNumeric =
|
||||
SHIFT_BIGNUMERIC;
|
||||
val shiftRightBigNumeric: Int64 -> BigNumeric -> BigNumeric =
|
||||
SHIFT_RIGHT_BIGNUMERIC;
|
||||
val toNumericBigNumeric: forall (n: nat). BigNumeric -> Numeric n =
|
||||
TO_NUMERIC_BIGNUMERIC;
|
||||
val toBigNumericNumeric: forall (n: nat). Numeric n -> BigNumeric =
|
||||
|
@ -569,7 +569,7 @@ private[lf] final class Compiler(
|
||||
case BSubBigNumeric => SBSubBigNumeric
|
||||
case BDivBigNumeric => SBDivBigNumeric
|
||||
case BMulBigNumeric => SBMulBigNumeric
|
||||
case BShiftBigNumeric => SBShiftBigNumeric
|
||||
case BShiftRightBigNumeric => SBShiftRightBigNumeric
|
||||
case BToBigNumericNumeric => SBToBigNumericNumeric
|
||||
case BToNumericBigNumeric => SBToNumericBigNumeric
|
||||
case BToTextBigNumeric => SBToText
|
||||
|
@ -911,14 +911,19 @@ private[lf] object SBuiltin {
|
||||
}
|
||||
}
|
||||
|
||||
final object SBShiftBigNumeric extends SBuiltinPure(2) {
|
||||
final object SBShiftRightBigNumeric extends SBuiltinPure(2) {
|
||||
override private[speedy] def executePure(args: util.ArrayList[SValue]): SBigNumeric = {
|
||||
val shifting = getSInt64(args, 0)
|
||||
if (shifting.abs > SBigNumeric.MaxPrecision) throw DamlEArithmeticError("overflow/underflow")
|
||||
rightOrArithmeticError(
|
||||
"overflow/underflow",
|
||||
SBigNumeric.fromBigDecimal(getSBigNumeric(args, 1).scaleByPowerOfTen(-shifting.toInt)),
|
||||
)
|
||||
val x = getSBigNumeric(args, 1)
|
||||
if (x.signum() == 0)
|
||||
SBigNumeric.Zero
|
||||
else if (shifting.abs > SBigNumeric.MaxPrecision)
|
||||
throw DamlEArithmeticError("overflow/underflow")
|
||||
else
|
||||
rightOrArithmeticError(
|
||||
"overflow/underflow",
|
||||
SBigNumeric.fromBigDecimal(x.scaleByPowerOfTen(-shifting.toInt)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,6 +268,8 @@ object SValue {
|
||||
def assertFromBigDecimal(x: java.math.BigDecimal): SBigNumeric =
|
||||
data.assertRight(fromBigDecimal(x))
|
||||
|
||||
val Zero: SBigNumeric = new SBigNumeric(java.math.BigDecimal.ZERO)
|
||||
|
||||
def checkScale(s: Long): Either[String, Int] =
|
||||
Either.cond(test = s.abs <= MaxScale, right = s.toInt, left = "invalide scale")
|
||||
}
|
||||
|
@ -145,16 +145,16 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
|
||||
val testCases = Table(
|
||||
"arguments" -> "success",
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:ten" -> false,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_BIGNUMERIC ${MinScale / 2} BigNumeric:one)" -> true,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one)" -> false,
|
||||
s"(SHIFT_BIGNUMERIC ${MaxScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"(SHIFT_BIGNUMERIC ${MaxScale} BigNumeric:one) (SHIFT_BIGNUMERIC 1 BigNumeric:one)" -> false,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_BIGNUMERIC ${MinScale / 2} BigNumeric:one)" -> true,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one)" -> false,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2} BigNumeric:underSqrtOfTen) (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:underSqrtOfTen)" -> true,
|
||||
s"(SHIFT_BIGNUMERIC ${MinScale / 2} BigNumeric:overSqrtOfTen) (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:overSqrtOfTen)" -> false,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:ten" -> false,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2} BigNumeric:one)" -> true,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one)" -> false,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MaxScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MaxScale} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC 1 BigNumeric:one)" -> false,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2} BigNumeric:one)" -> true,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one)" -> false,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2} BigNumeric:underSqrtOfTen) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:underSqrtOfTen)" -> true,
|
||||
s"(SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2} BigNumeric:overSqrtOfTen) (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:overSqrtOfTen)" -> false,
|
||||
)
|
||||
|
||||
forEvery(testCases)((args, success) =>
|
||||
@ -167,40 +167,40 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
"throws an exception in case of overflow" in {
|
||||
val testCases = Table(
|
||||
"arguments" -> "success",
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale / 2} BigNumeric:one) (SHIFT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:one)" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:one)" -> false,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale} BigNumeric:one) (SHIFT_BIGNUMERIC 1 BigNumeric:one)" -> false,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:underSqrtOfTen) (SHIFT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:overSqrtOfTen)" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:overSqrtOfTen) (SHIFT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:overSqrtOfTen)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:twentyEight (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:twentyNine (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:nineteen (SHIFT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:one)" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:one)" -> false,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale} BigNumeric:one) BigNumeric:one" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale} BigNumeric:one) (SHIFT_RIGHT_BIGNUMERIC 1 BigNumeric:one)" -> false,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:underSqrtOfTen) (SHIFT_RIGHT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:overSqrtOfTen)" -> true,
|
||||
s"-1000 ROUNDING_DOWN (SHIFT_RIGHT_BIGNUMERIC ${MinScale / 2 - 1} BigNumeric:overSqrtOfTen) (SHIFT_RIGHT_BIGNUMERIC ${-(MinScale / 2 - 1)} BigNumeric:overSqrtOfTen)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:two)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:twentyEight (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:twentyNine (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:three)" -> false,
|
||||
s"${MinScale} ROUNDING_UP BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_DOWN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_CEILING BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_FLOOR BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_UP BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
s"${MinScale} ROUNDING_HALF_DOWN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> true,
|
||||
s"${MinScale} ROUNDING_HALF_EVEN BigNumeric:nineteen (SHIFT_RIGHT_BIGNUMERIC ${-MinScale} BigNumeric:minusTwo)" -> false,
|
||||
)
|
||||
forEvery(testCases)((args, success) =>
|
||||
eval(e"DIV_BIGNUMERIC $args") shouldBe (if (success) a[Right[_, _]] else a[Left[_, _]])
|
||||
@ -264,7 +264,7 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
|
||||
}
|
||||
|
||||
"SHIFT_BIGNUMERIC" - {
|
||||
"SHIFT_RIGHT_BIGNUMERIC" - {
|
||||
import java.math.BigDecimal
|
||||
import SBigNumeric.assertFromBigDecimal
|
||||
|
||||
@ -282,7 +282,7 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
)
|
||||
forEvery(testCases) { (inputScale, shifting, input, output) =>
|
||||
eval(
|
||||
e"SHIFT_BIGNUMERIC $shifting (TO_BIGNUMERIC_NUMERIC @$inputScale $input)"
|
||||
e"SHIFT_RIGHT_BIGNUMERIC $shifting (TO_BIGNUMERIC_NUMERIC @$inputScale $input)"
|
||||
) shouldBe Right(assertFromBigDecimal(new BigDecimal(output)))
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,6 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
"throws an exception in case of underflow/overflow" in {
|
||||
val testCases = Table(
|
||||
"arguments" -> "success",
|
||||
"0 BigNumeric:maxPositive" -> true,
|
||||
"1 BigNumeric:maxPositive" -> false,
|
||||
"-1 BigNumeric:maxPositive" -> false,
|
||||
s"${MaxScale} BigNumeric:one" -> true,
|
||||
@ -300,9 +299,31 @@ class SBuiltinBigNumericTest extends AnyFreeSpec with Matchers with TableDrivenP
|
||||
)
|
||||
|
||||
forEvery(testCases)((args, success) =>
|
||||
eval(e"SHIFT_BIGNUMERIC $args") shouldBe (if (success) a[Right[_, _]] else a[Left[_, _]])
|
||||
eval(e"SHIFT_RIGHT_BIGNUMERIC $args") shouldBe (if (success) a[Right[_, _]]
|
||||
else a[Left[_, _]])
|
||||
)
|
||||
}
|
||||
|
||||
"never throw an exception when trying to shifting 0" in {
|
||||
val testCases = Table(
|
||||
"argument",
|
||||
Long.MinValue,
|
||||
Int.MinValue.toLong,
|
||||
MinScale.toLong - 1,
|
||||
MinScale.toLong,
|
||||
-1L,
|
||||
0L,
|
||||
1L,
|
||||
MaxScale.toLong,
|
||||
MaxScale.toLong + 1,
|
||||
Int.MaxValue.toLong,
|
||||
Long.MaxValue,
|
||||
)
|
||||
forEvery(testCases)(arg =>
|
||||
eval(e"SHIFT_RIGHT_BIGNUMERIC $arg BigNumeric:zero") shouldBe Right(SBigNumeric.Zero)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,19 +356,19 @@ object SBuiltinBigNumericTest {
|
||||
val twentyNine: BigNumeric =
|
||||
TO_BIGNUMERIC_NUMERIC @0 29.;
|
||||
val minPositive: BigNumeric =
|
||||
SHIFT_BIGNUMERIC BigNumeric:maxScale BigNumeric:one;
|
||||
SHIFT_RIGHT_BIGNUMERIC BigNumeric:maxScale BigNumeric:one;
|
||||
val maxPositive: BigNumeric =
|
||||
let x: BigNumeric = SUB_BIGNUMERIC BigNumeric:one BigNumeric:minPositive in
|
||||
ADD_BIGNUMERIC x (SHIFT_BIGNUMERIC (SUB_INT64 0 BigNumeric:maxScale) x);
|
||||
ADD_BIGNUMERIC x (SHIFT_RIGHT_BIGNUMERIC (SUB_INT64 0 BigNumeric:maxScale) x);
|
||||
val maxNegative: BigNumeric =
|
||||
SHIFT_BIGNUMERIC BigNumeric:maxScale BigNumeric:minusOne;
|
||||
SHIFT_RIGHT_BIGNUMERIC BigNumeric:maxScale BigNumeric:minusOne;
|
||||
val minNegative: BigNumeric =
|
||||
let x: BigNumeric = ADD_BIGNUMERIC BigNumeric:minusOne BigNumeric:minPositive in
|
||||
ADD_BIGNUMERIC x (SHIFT_BIGNUMERIC (SUB_INT64 0 BigNumeric:maxScale) x);
|
||||
ADD_BIGNUMERIC x (SHIFT_RIGHT_BIGNUMERIC (SUB_INT64 0 BigNumeric:maxScale) x);
|
||||
|
||||
val tenPower: Int64 -> BigNumeric = \(n: Int64) ->
|
||||
SHIFT_BIGNUMERIC (SUB_INT64 0 n) BigNumeric:one;
|
||||
val x: BigNumeric = SHIFT_BIGNUMERIC ${SValue.SBigNumeric.MinScale} (TO_BIGNUMERIC_NUMERIC @0 5.);
|
||||
SHIFT_RIGHT_BIGNUMERIC (SUB_INT64 0 n) BigNumeric:one;
|
||||
val x: BigNumeric = SHIFT_RIGHT_BIGNUMERIC ${SValue.SBigNumeric.MinScale} (TO_BIGNUMERIC_NUMERIC @0 5.);
|
||||
val almostX: BigNumeric = SUB_BIGNUMERIC BigNumeric:x BigNumeric:minPositive;
|
||||
val minusX: BigNumeric = SUB_BIGNUMERIC BigNumeric:zero BigNumeric:x;
|
||||
}
|
||||
|
@ -453,7 +453,8 @@ object Ast {
|
||||
final case object BMulBigNumeric extends BuiltinFunction // : BigNumeric → BigNumeric → BigNumeric
|
||||
final case object BDivBigNumeric
|
||||
extends BuiltinFunction // : Int64 -> RoundingMode → BigNumeric → BigNumeric → BigNumeric s
|
||||
final case object BShiftBigNumeric extends BuiltinFunction // : Int64 → BigNumeric → BigNumeric
|
||||
final case object BShiftRightBigNumeric
|
||||
extends BuiltinFunction // : Int64 → BigNumeric → BigNumeric
|
||||
final case object BToNumericBigNumeric extends BuiltinFunction // : ∀s. BigNumeric → Numeric s
|
||||
final case object BToBigNumericNumeric extends BuiltinFunction // : ∀s. Numeric s → BigNumeric
|
||||
final case object BToTextBigNumeric extends BuiltinFunction // : BigNumeric → Text
|
||||
|
@ -319,7 +319,7 @@ private[parser] class ExprParser[P](parserParameters: ParserParameters[P]) {
|
||||
"SUB_BIGNUMERIC" -> BSubBigNumeric,
|
||||
"MUL_BIGNUMERIC" -> BMulBigNumeric,
|
||||
"DIV_BIGNUMERIC" -> BDivBigNumeric,
|
||||
"SHIFT_BIGNUMERIC" -> BShiftBigNumeric,
|
||||
"SHIFT_RIGHT_BIGNUMERIC" -> BShiftRightBigNumeric,
|
||||
"TO_NUMERIC_BIGNUMERIC" -> BToNumericBigNumeric,
|
||||
"TO_BIGNUMERIC_NUMERIC" -> BToBigNumericNumeric,
|
||||
"TO_TEXT_BIGNUMERIC" -> BToTextBigNumeric,
|
||||
|
@ -3842,6 +3842,14 @@ BigNumeric functions
|
||||
|
||||
[*Available in version ≥ 1.13*]
|
||||
|
||||
* ``SHIFT_RIGHT_BIGNUMERIC : 'Int64' → 'BigNumeric' → 'BigNumeric'``
|
||||
|
||||
Multiply the second argument by 10 to the negative power of the first
|
||||
argument. Throws an ``ArithmeticError`` in case the result cannot be
|
||||
represented without loss of precision.
|
||||
|
||||
[*Available in version ≥ 1.13*]
|
||||
|
||||
* ``TO_TEXT_BIGNUMERIC : 'BigNumeric' → 'Text'``
|
||||
|
||||
Returns the numeric string representation of the BigNumeric. The
|
||||
|
@ -230,7 +230,7 @@ private[validation] object Typing {
|
||||
BSubBigNumeric -> (TBigNumeric ->: TBigNumeric ->: TBigNumeric),
|
||||
BMulBigNumeric -> (TBigNumeric ->: TBigNumeric ->: TBigNumeric),
|
||||
BDivBigNumeric -> (TInt64 ->: TRoundingMode ->: TBigNumeric ->: TBigNumeric ->: TBigNumeric),
|
||||
BShiftBigNumeric -> (TInt64 ->: TBigNumeric ->: TBigNumeric),
|
||||
BShiftRightBigNumeric -> (TInt64 ->: TBigNumeric ->: TBigNumeric),
|
||||
BToNumericBigNumeric -> TForall(alpha.name -> KNat, TBigNumeric ->: TNumeric(alpha)),
|
||||
BToBigNumericNumeric -> TForall(alpha.name -> KNat, TNumeric(alpha) ->: TBigNumeric),
|
||||
BToTextBigNumeric -> (TBigNumeric ->: TText),
|
||||
|
Loading…
Reference in New Issue
Block a user