gchq/CyberChef · error · OperationError

Fractional values are not supported by BCD

Error message

Fractional values are not supported by BCD

What it means

To BCD only encodes integer values; it rejects any number whose integer-truncated value differs from itself (i.e. numbers with a non-zero fractional part). BCD stores whole decimal digits and has no representation for a fractional component in this implementation.

Source

Thrown at src/core/operations/ToBCD.mjs:63

            },
            {
                "name": "Output format",
                "type": "option",
                "value": FORMAT
            }
        ];
    }

    /**
     * @param {BigNumber} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        if (input.isNaN())
            throw new OperationError("Invalid input");
        if (!input.integerValue(BigNumber.ROUND_DOWN).isEqualTo(input))
            throw new OperationError("Fractional values are not supported by BCD");

        const encoding = ENCODING_LOOKUP[args[0]],
            packed = args[1],
            signed = args[2],
            outputFormat = args[3];

        // Split input number up into separate digits
        const digits = input.toFixed().split("");

        if (digits[0] === "-" || digits[0] === "+") {
            digits.shift();
        }

        let nibbles = [];

        digits.forEach(d => {
            const n = parseInt(d, 10);
            nibbles.push(encoding[n]);

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Round or truncate the input to a whole number before To BCD.
  2. Multiply and round if you need to preserve fixed-point scale, then document the scale separately.
  3. Filter out fractional inputs upstream.

Example fix

// before: input = 12.5            -> fractional, throws
// after:  input = Math.round(12.5)  // 13  -> integer, BCD encodes 1,3
Defensive patterns

Strategy: validation

Validate before calling

if (!input.integerValue(BigNumber.ROUND_DOWN).isEqualTo(input)) {
  throw new Error("To BCD requires an integer");
}

Type guard

const isIntegerBN = v => v.integerValue(BigNumber.ROUND_DOWN).isEqualTo(v);

Try / catch

try { toBcd(input, ...args); }
catch (e) { if (/Fractional/.test(e.message)) { input = input.integerValue(BigNumber.ROUND_HALF_UP); } else throw e; }

Prevention

When it happens

Trigger: Passing a fractional number such as 12.5 or -3.14 to To BCD. The guard compares the ROUND_DOWN integer to the original and throws when they are unequal.

Common situations: Forggetting to truncate/round a measurement or currency value; receiving floats from upstream arithmetic.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/ce6b9d46ff3c4f24. Report an issue: GitHub.